[1. Playbook 基本结构](#1. Playbook 基本结构)
[2. Tasks 模块](#2. Tasks 模块)
[3. Variables 模块](#3. Variables 模块)
[4. Templates 模块(Jinja2 模板)](#4. Templates 模块(Jinja2 模板))
[5. Handlers 模块](#5. Handlers 模块)
[6. Tags 模块](#6. Tags 模块)
[7. 条件判断 when](#7. 条件判断 when)
[8. 循环 with_items / loop](#8. 循环 with_items / loop)
[9.Roles 模块详解](#9.Roles 模块详解)
[Roles 的概念](#Roles 的概念)
[Roles 的目录结构](#Roles 的目录结构)
[创建 Roles 的步骤](#创建 Roles 的步骤)
[创建 roles 目录](#创建 roles 目录)
[在各目录创建 main.yml 文件](#在各目录创建 main.yml 文件)
[在 Roles 中定义任务和变量](#在 Roles 中定义任务和变量)
[在 Playbook 中调用 Roles](#在 Playbook 中调用 Roles)
[Roles 与变量的灵活使用](#Roles 与变量的灵活使用)
[Roles 依赖关系(meta/main.yml)](#Roles 依赖关系(meta/main.yml))
[10. 总结](#10. 总结)
前言
Ansible 的 Playbook 是自动化运维的核心工具,它用 YAML 文件描述在远程主机上执行的一系列任务。本文详细介绍 Playbook 的结构及其各模块的概念、用途和写法,适合初学者和有经验的运维人员查阅。
1. Playbook 基本结构
Playbook 由一个或多个 Play 组成,每个 Play 负责对一组主机执行任务。主要模块:
模块 | 概念 | 用途 |
---|---|---|
Tasks | 定义要执行的具体任务,每个任务调用一个模块(如 yum 、copy ) |
控制任务执行顺序 |
Variables | 变量,使 Playbook 灵活可复用 | 在不同主机间传递不同值 |
Templates | Jinja2 模板,动态生成文件 | 自动化配置文件生成 |
Handlers | 响应任务变更(由 notify 触发) |
常用于服务重启、刷新配置 |
Tags | 给任务打标签 | 执行 Playbook 时只执行特定任务 |
Roles | 模块化组织 Playbook | 管理复杂剧本、提高复用性 |
2. Tasks 模块
概念
Tasks 是 Playbook 中的"执行单元"。每个任务调用一个 Ansible 模块在远程主机上执行操作。
用法
tasks:
- name: 测试连通性
ping:
- name: 安装软件包
yum: name=httpd state=latest
- name: 停止防火墙
service: name=firewalld state=stopped
Tips:
任务按顺序执行
每个任务尽量有
name
方便查看日志可用
ignore_errors: true
忽略失败继续执行
3. Variables 模块
概念
变量用于提高 Playbook 的通用性和可维护性。变量可以在 Playbook 中用 vars
定义,也可以通过命令行 -e
传递,还可以在 Inventory 中定义主机变量。
用法
- hosts: dbservers
vars:
groupname: mysql
username: nginx
tasks:
- name: 创建组
group: name={{ groupname }} system=yes gid=306
- name: 创建用户
user: name={{ username }} uid=306 group={{ groupname }}
命令行传递变量:
ansible-playbook test.yaml -e "username=nginx"
4. Templates 模块(Jinja2 模板)
概念
模板用于动态生成配置文件。通过 Jinja2 语法,把变量写进模板文件,执行 Playbook 时替换成真实值。
用法
- 创建模板文件(以
.j2
为后缀):
# /opt/httpd.conf.j2
Listen {{ http_port }}
ServerName {{ server_name }}
DocumentRoot "{{ root_dir }}"
- 在主机清单定义变量:
[webservers]
192.168.10.14 http_port=80 server_name=www.accp.com root_dir=/etc/httpd/htdocs
- 在 Playbook 中调用模板:
- hosts: webservers
tasks:
- name: 安装配置文件
template: src=/opt/httpd.conf.j2 dest=/etc/httpd/conf/httpd.conf
5. Handlers 模块
概念
Handlers 是特殊任务,用于响应普通任务的变更,通常结合 notify
使用,例如配置文件更新后自动重启服务。
用法
tasks:
- name: 拷贝配置文件
copy: src=/opt/httpd.conf dest=/etc/httpd/conf/httpd.conf
notify: restart httpd
handlers:
- name: restart httpd
service: name=httpd state=restarted
Tips:
Handlers 在 Play 执行完所有普通任务后统一执行
多次
notify
同一 handler 只执行一次
6. Tags 模块
概念
Tags 用于给任务打标签,执行 Playbook 时可以指定只执行特定标签的任务。
用法
tasks:
- name: 拷贝 hosts 文件
copy: src=/etc/hosts dest=/opt/hosts
tags: [only]
- name: 永远执行的任务
file: path=/opt/testhost state=touch
tags: [always]
执行:
ansible-playbook play.yaml --tags="only"
Tips :
always
标签的任务无论执行哪个 tags 都会执行。
7. 条件判断 when
概念
when
用于按条件执行任务,只在条件为 true
时执行。
用法
tasks:
- name: 仅在特定 IP 上重启
command: /sbin/shutdown -r now
when: ansible_default_ipv4.address == "192.168.10.14"
- name: 按主机名判断
debug: msg="This is myhost"
when: inventory_hostname == "myhost"
8. 循环 with_items
/ loop
概念
循环可批量执行相似任务,比如批量创建目录或用户。
用法
- name: 创建多个目录
file:
path: "{{ item }}"
state: directory
with_items:
- /tmp/test1
- /tmp/test2
- name: 创建多个用户
user: name={{ item.name }} state=present groups={{ item.groups }}
with_items:
- { name: test1, groups: wheel }
- { name: test2, groups: root }
Tips :
loop
是 Ansible 2.5+ 推荐用法,功能与with_items
相同。
9.Roles 模块详解
Roles 的概念
在 Ansible 中,随着 Playbook 的功能越来越多、越来越复杂,单个 YAML 文件可能包含几十上百个任务,难以管理和复用。 **Roles(角色)**就是为了解决这个问题而设计的:
-
把变量、任务、模板、文件、处理程序等按照固定目录结构分类存放
-
自动按约定位置加载文件
-
支持在不同 Playbook 中重复使用相同的角色
-
适合按"功能"组织(例如 httpd、mysql、php),提高可维护性
简而言之,Roles 就是把 Playbook 模块化。
Roles 的目录结构
每个 Role 都在 roles/
目录下有一个独立的子目录:
roles/
└── httpd/
├── files/ # copy、script 模块调用的文件
├── templates/ # 模板文件,template 模块自动在此目录查找
├── tasks/ # 必须有 main.yml,定义任务列表
├── handlers/ # 必须有 main.yml,定义处理程序(notify 响应)
├── vars/ # 必须有 main.yml,定义角色使用的变量
├── defaults/ # 必须有 main.yml,定义角色的默认变量(优先级最低)
└── meta/ # 必须有 main.yml,定义角色依赖关系、特殊设定
注意:
tasks/main.yml
是角色的入口文件(必须存在)
handlers/vars/defaults/meta
下的 main.yml 文件名也必须固定用不到的目录可以不建
创建 Roles 的步骤
创建 roles
目录
mkdir -p /etc/ansible/roles
创建角色目录和子目录
以 httpd
角色为例:
mkdir -p /etc/ansible/roles/httpd/{files,templates,tasks,handlers,vars,defaults,meta}
在各目录创建 main.yml 文件
touch /etc/ansible/roles/httpd/{defaults,vars,tasks,meta,handlers}/main.yml
在 Roles 中定义任务和变量
任务文件(tasks/main.yml):
# /etc/ansible/roles/httpd/tasks/main.yml
- name: 安装 Apache
yum: name={{pkg}} state=latest
- name: 启动 Apache
service: enabled=true name={{svc}} state=started
变量文件(vars/main.yml):
# /etc/ansible/roles/httpd/vars/main.yml
pkg: httpd
svc: httpd
小技巧:
一般把角色专用变量写在
vars/main.yml
把默认变量写在
defaults/main.yml
(用户可以覆盖)全局变量可以写在
/etc/ansible/group_vars/all
在 Playbook 中调用 Roles
创建 site.yml
(或任意 Playbook):
# /etc/ansible/site.yml
---
- hosts: webservers
remote_user: root
roles:
- httpd # 调用 httpd 角色
如果有多个角色,按顺序写:
roles:
- httpd
- mysql
- php
执行:
cd /etc/ansible
ansible-playbook site.yml
Roles 与变量的灵活使用
-
角色变量 :写在
roles/<role>/vars/main.yml
,作用范围仅限当前角色 -
默认变量 :写在
roles/<role>/defaults/main.yml
,优先级最低,便于用户在外部覆盖 -
主机/组变量 :写在
/etc/ansible/hosts
或group_vars/
中 -
命令行变量 :用
-e
覆盖一切
例子:
ansible-playbook site.yml -e "pkg=nginx svc=nginx"
Roles 依赖关系(meta/main.yml)
如果某个角色依赖于其他角色,可以在 meta/main.yml
中定义:
# /etc/ansible/roles/php/meta/main.yml
dependencies:
- role: httpd
- role: mysql
这样在调用 php
角色时,会自动先执行 httpd
和 mysql
角色。
综合案例
# 创建角色
mkdir -p /etc/ansible/roles/{httpd,mysql,php}/{files,templates,tasks,handlers,vars,defaults,meta}
touch /etc/ansible/roles/{httpd,mysql,php}/{defaults,vars,tasks,meta,handlers}/main.yml
httpd/tasks/main.yml
- name: install apache
yum: name={{pkg}} state=latest
- name: start apache
service: enabled=true name={{svc}} state=started
httpd/vars/main.yml
pkg: httpd
svc: httpd
mysql/vars/main.yml
pkg:
- mariadb
- mariadb-server
svc: mariadb
php/vars/main.yml
pkg:
- php
- php-fpm
svc: php-fpm
site.yml
---
- hosts: webservers
remote_user: root
roles:
- httpd
- mysql
- php
执行:
cd /etc/ansible
ansible-playbook site.yml
效果:在 webservers 主机组上依次安装 httpd、mysql、php 并启动服务。
10. 总结
-
Tasks 是执行单元
-
Variables 提供灵活性
-
Templates 动态生成配置文件
-
Handlers 响应变更,统一处理
-
Tags 定向执行特定任务
-
when/loop 控制条件和循环
-
Roles 模块化管理大型 Playbook