Ansible Playbook 使用 YAML 格式编写,通过定义任务流程实现自动化。以下是 Playbook 的核心结构、关键字和语法详解:
一、Playbook 基础结构
1. 基本框架
---
- name: Play 1 Description # Play 的名称
hosts: target_host_group # 目标主机组(来自 Inventory)
become: yes # 是否提权(sudo)
vars: # 定义变量
http_port: 80
tasks: # 任务列表
- name: Task 1 # 任务名称
module_name: # 模块名称(如 apt, copy)
module_parameter: value
- name: Play 2 Description # 另一个 Play(按顺序执行)
hosts: another_group
tasks: [...]
二、核心关键字详解
1. Play 级别关键字
关键字 | 说明 |
---|---|
name |
Play 的描述性名称(可选,但推荐使用) |
hosts |
目标主机组或主机模式(如 web_servers 或 192.168.1.* ) |
become |
是否提权(默认 no ),等同于 sudo |
vars |
定义 Play 级变量 |
vars_files |
引入外部变量文件(如 vars/main.yml ) |
tasks |
定义任务列表 |
handlers |
定义处理器(由任务触发,如重启服务) |
roles |
引入角色(模块化复用代码) |
pre_tasks |
在 tasks 前执行的任务列表 |
post_tasks |
在 tasks 后执行的任务列表 |
environment |
设置环境变量 |
any_errors_fatal |
任一任务失败时终止整个 Play(默认 no ) |
2. Task 级别关键字
关键字 | 说明 |
---|---|
name |
任务的描述(必填,清晰描述任务作用) |
module |
调用的 Ansible 模块(如 apt , copy ) |
args |
模块参数(替代行内参数写法,适用于复杂场景) |
when |
条件判断(仅在条件满足时执行任务) |
loop |
循环执行任务(替代旧版 with_items ) |
register |
将任务结果保存到变量 |
ignore_errors |
忽略任务失败(默认 no ) |
changed_when |
定义任务何时标记为 "changed" 状态 |
failed_when |
定义任务何时标记为 "failed" 状态 |
tags |
为任务打标签,方便选择性执行 |
retries |
任务失败重试次数(常与 until 结合) |
delay |
重试间隔时间(秒) |
until |
重试直到条件满足 |
3. Handler 关键字
handlers:
- name: restart_nginx
service:
name: nginx
state: restarted
由任务中的
notify
触发,按定义顺序执行。仅在所有任务执行完毕后触发一次(即使被多次通知)。
三、语法细节与示例
1. YAML 格式要求
缩进:使用 2 个空格(非 Tab)。
列表:以
-
开头。字符串:可省略引号,但包含特殊字符时需用
"
或'
包裹。
2. 变量定义与引用
vars:
package_name: nginx
config_path: "/etc/{{ package_name }}/nginx.conf"
tasks:
- name: Install Package
apt:
name: "{{ package_name }}"
3. 条件判断 (when
)
- name: Install EPEL on CentOS
yum:
name: epel-release
state: present
when: ansible_os_family == 'RedHat'
4. 循环 (loop
)
- name: Add Users
user:
name: "{{ item }}"
state: present
loop:
- user1
- user2
5. 错误处理
- name: Ignore Failed Task
command: /bin/false
ignore_errors: yes
- name: Retry Task
shell: /opt/start_service.sh
retries: 3
delay: 10
6. 注册变量 (register
)
- name: Check Service Status
command: systemctl is-active nginx
register: service_status
- name: Debug Status
debug:
var: service_status.stdout
四、模块化与复用
1. Include 与 Import
方法 | 说明 |
---|---|
import_playbook |
导入另一个 Playbook(静态,预处理阶段解析) |
import_tasks |
导入任务文件(静态) |
include_tasks |
动态包含任务文件(根据条件或循环动态加载) |
示例:
- name: Include Common Tasks
import_tasks: common_tasks.yml
2. Roles 结构
roles/
webserver/
tasks/ # 主任务文件
main.yml
handlers/ # 处理器
main.yml
templates/ # Jinja2 模板
nginx.conf.j2
files/ # 静态文件
index.html
vars/ # 角色变量
main.yml
defaults/ # 默认变量(优先级最低)
main.yml
meta/ # 依赖声明
main.yml
使用角色:
- name: Apply Web Server Role
hosts: web_servers
roles:
- webserver
五、高级功能
1. 加密敏感数据 (Vault)
# 加密文件
ansible-vault encrypt vars/secrets.yml
# 运行 Playbook 时解密
ansible-playbook site.yml --ask-vault-pass
2. 动态 Inventory
# inventory.ini
[web_servers]
localhost ansible_connection=local
[all:vars]
ansible_python_interpreter=/usr/bin/python3
3. 异步任务
- name: Long Running Task
command: /path/to/long_script.sh
async: 3600 # 最大运行时间(秒)
poll: 0 # 不等待结果
register: async_result
- name: Check Async Task
async_status:
jid: "{{ async_result.ansible_job_id }}"
register: job_result
until: job_result.finished
retries: 30
六、调试与验证
1. 语法检查
ansible-playbook playbook.yml --syntax-check
2. 空运行 (Dry Run)
ansible-playbook playbook.yml --check
3. 详细日志
ansible-playbook playbook.yml -v # -v 到 -vvvv(详细程度递增)
4. 标签执行
tasks:
- name: Install Packages
apt: name=nginx
tags: install
- name: Copy Config
copy: src=nginx.conf dest=/etc/nginx/
tags: config
ansible-playbook playbook.yml --tags "install,config"
七、最佳实践
命名清晰:为 Play 和 Task 使用有意义的名称。
模块优先:尽量使用 Ansible 内置模块而非原始 Shell 命令。
变量分离:敏感数据通过 Vault 加密,通用变量放在
group_vars/
或host_vars/
。幂等性:确保任务可重复执行且结果一致(如使用
state: present
而非latest
)。版本控制:将 Playbook 和 Roles 纳入 Git 管理。
八、完整 Playbook 示例
---
- name: Configure Web Server
hosts: web_servers
become: yes
vars:
http_port: 8080
max_clients: 200
vars_files:
- vars/secrets.yml
tasks:
- name: Install Nginx
apt:
name: nginx
state: present
tags: install
- name: Copy Nginx Config
template:
src: templates/nginx.conf.j2
dest: /etc/nginx/nginx.conf
notify: Restart Nginx
tags: config
- name: Ensure Nginx Running
service:
name: nginx
state: started
enabled: yes
tags: service
handlers:
- name: Restart Nginx
service:
name: nginx
state: restarted