Ansible Playbook编写详解
Ansible Playbook是Ansible的核心组件,它是一种基于YAML语言的配置管理工具,用于自动化部署、配置管理和应用编排。本教程将详细介绍Ansible Playbook的编写方法,包含结构、语法、常用模块和最佳实践。
1. Playbook基本结构
Playbook是由一个或多个"play"组成的YAML文件,每个play定义一组在特定主机上执行的任务。基本结构如下:
---
- name: 安装和配置Nginx
hosts: webservers
become: yes
vars:
http_port: 80
max_clients: 200
tasks:
- name: 安装Nginx
ansible.builtin.apt:
name: nginx
state: present
- name: 启动Nginx服务
ansible.builtin.service:
name: nginx
state: started
enabled: yes
结构解析:
- `---`:YAML文档开始标记
- `- name`:play名称,描述此play的目的
- `hosts`:指定目标主机或主机组
- `become`:是否使用特权执行(默认为sudo)
- `vars`:定义变量
- `tasks`:任务列表,每个任务使用模块执行特定操作
2. 常用核心模块
2.1 包管理模块
---
- name: 包管理示例
hosts: all
become: yes
tasks:
- name: 安装最新版Apache (Ubuntu)
ansible.builtin.apt:
name: apache2
state: latest
when: ansible_os_family == "Debian"
- name: 安装最新版Apache (CentOS)
ansible.builtin.yum:
name: httpd
state: latest
when: ansible_os_family == "RedHat"
2.2 服务管理模块
---
- name: 服务管理示例
hosts: webservers
become: yes
tasks:
- name: 确保Nginx服务运行
ansible.builtin.service:
name: nginx
state: started
enabled: yes
- name: 重启Nginx服务
ansible.builtin.service:
name: nginx
state: restarted
2.3 文件操作模块
---
- name: 文件操作示例
hosts: all
tasks:
- name: 创建目录
ansible.builtin.file:
path: /opt/myapp
state: directory
mode: '0755'
- name: 复制配置文件
ansible.builtin.copy:
src: files/myapp.conf
dest: /etc/myapp.conf
owner: root
group: root
mode: '0644'
backup: yes
2.4 命令执行模块
---
- name: 命令执行示例
hosts: all
tasks:
- name: 安全执行命令
ansible.builtin.command:
cmd: echo "Hello World" > /tmp/hello.txt
creates: /tmp/hello.txt
- name: 执行带条件的shell命令
ansible.builtin.shell:
cmd: |
if [ ! -f /tmp/lockfile ]; then
touch /tmp/lockfile
echo "Lock file created"
fi
3. 变量使用
3.1 定义变量
---
- name: 变量使用示例
hosts: all
vars:
package_name: nginx
config_file: /etc/nginx/nginx.conf
tasks:
- name: 安装软件包
ansible.builtin.apt:
name: "{{ package_name }}"
state: present
- name: 备份配置文件
ansible.builtin.copy:
src: "{{ config_file }}"
dest: "{{ config_file }}.bak"
remote_src: yes
3.2 变量文件
创建`vars/main.yml`:
---
nginx_port: 80
nginx_worker_processes: auto
nginx_keepalive_timeout: 65
在Playbook中使用:
---
- name: 使用变量文件
hosts: webservers
vars_files:
- vars/main.yml
tasks:
- name: 配置Nginx
ansible.builtin.template:
src: templates/nginx.conf.j2
dest: /etc/nginx/nginx.conf
notify: Restart Nginx
handlers:
- name: Restart Nginx
ansible.builtin.service:
name: nginx
state: restarted
4. 条件判断和循环
4.1 条件判断
---
- name: 条件判断示例
hosts: all
tasks:
- name: 安装特定版本的Python
ansible.builtin.apt:
name: python3.9
state: present
when:
- ansible_os_family == "Debian"
- ansible_distribution_version == "20.04"
4.2 循环结构
---
- name: 循环示例
hosts: all
tasks:
- name: 创建多个用户
ansible.builtin.user:
name: "{{ item }}"
state: present
loop:
- user1
- user2
- user3
- name: 安装多个软件包
ansible.builtin.apt:
name: "{{ item.name }}"
state: "{{ item.state }}"
loop:
- { name: 'nginx', state: 'present' }
- { name: 'mysql-server', state: 'present' }
- { name: 'php-fpm', state: 'absent' }
5. 模板和配置管理
创建模板文件`templates/nginx.conf.j2`:
user www-data;
worker_processes {{ nginx_worker_processes }};
pid /run/nginx.pid;
events {
worker_connections 768;
}
http {
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout {{ nginx_keepalive_timeout }};
types_hash_max_size 2048;
include /etc/nginx/mime.types;
default_type application/octet-stream;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
server {
listen {{ nginx_port }};
root /var/www/html;
index index.html;
location / {
try_files $uri $uri/ =404;
}
}
}
在Playbook中使用模板:
---
- name: 配置Nginx
hosts: webservers
become: yes
tasks:
- name: 部署Nginx配置
ansible.builtin.template:
src: templates/nginx.conf.j2
dest: /etc/nginx/nginx.conf
owner: root
group: root
mode: '0644'
validate: 'nginx -t -c %s'
notify: Restart Nginx
handlers:
- name: Restart Nginx
ansible.builtin.service:
name: nginx
state: restarted
6. 错误处理和调试
6.1 忽略错误
---
- name: 忽略错误示例
hosts: all
tasks:
- name: 尝试删除可能不存在的文件
ansible.builtin.file:
path: /tmp/nonexistent_file
state: absent
ignore_errors: yes
6.2 调试任务
---
- name: 调试示例
hosts: all
tasks:
- name: 显示系统信息
ansible.builtin.debug:
msg: |
主机名: {{ ansible_hostname }}
操作系统: {{ ansible_distribution }}
内核版本: {{ ansible_kernel }}
- name: 显示变量内容
ansible.builtin.debug:
var: ansible_facts
7. 角色组织
创建角色结构:
site.yml
webservers.yml
roles/
common/
tasks/
handlers/
files/
templates/
vars/
defaults/
meta/
nginx/
tasks/
handlers/
files/
templates/
vars/
defaults/
meta/
示例角色任务`roles/nginx/tasks/main.yml`:
---
- name: 安装Nginx
ansible.builtin.apt:
name: nginx
state: present
- name: 部署配置文件
ansible.builtin.template:
src: nginx.conf.j2
dest: /etc/nginx/nginx.conf
notify: Restart Nginx
- name: 确保Nginx运行
ansible.builtin.service:
name: nginx
state: started
enabled: yes
在Playbook中使用角色:
---
- name: 配置Web服务器
hosts: webservers
become: yes
roles:
- common
- nginx
- { role: php, when: ansible_os_family == "Debian" }
8. 高级技巧
8.1 块和错误处理
---
- name: 块和错误处理示例
hosts: all
tasks:
- name: 尝试安装并配置服务
block:
- name: 安装软件包
ansible.builtin.apt:
name: "{{ package_name }}"
state: present
- name: 启动服务
ansible.builtin.service:
name: "{{ service_name }}"
state: started
rescue:
- name: 回滚操作
ansible.builtin.debug:
msg: "安装失败,执行回滚操作"
- name: 卸载软件包
ansible.builtin.apt:
name: "{{ package_name }}"
state: absent
always:
- name: 记录日志
ansible.builtin.debug:
msg: "操作执行完成"
8.2 动态包含
---
- name: 动态包含任务
hosts: all
tasks:
- name: 包含基于变量的任务
include_tasks: "tasks/{{ ansible_os_family }}.yml"
8.3 标签使用
---
- name: 标签示例
hosts: all
tasks:
- name: 安装基础包
ansible.builtin.apt:
name: "{{ item }}"
loop:
- curl
- wget
- git
tags: ['packages', 'base']
- name: 配置防火墙
ansible.builtin.ufw:
state: enabled
tags: ['security', 'firewall']
运行特定标签的任务:
ansible-playbook site.yml --tags "packages"
ansible-playbook site.yml --skip-tags "firewall"
9. 最佳实践
1. 保持幂等性:确保任务多次执行结果一致
2. 使用角色:组织复杂配置为可重用组件
3. 版本控制:将所有Playbook和配置文件纳入Git
4. 测试驱动开发:使用Molecule测试角色
5. 模块化设计:小而专一的任务优于大而复杂的任务
6. 变量外部化:敏感信息使用Vault加密
7. 文档化:为每个角色和Playbook添加README
8. 命名规范:使用一致的命名约定
总结
Ansible Playbook是一种强大而灵活的自动化工具,通过YAML语法定义系统配置和部署流程。本教程详细介绍了Playbook的基本结构、常用模块、变量使用、条件判断、循环结构、模板管理、错误处理和角色组织等核心概念。
关键要点:
1. Playbook使用YAML语法,基于主机、变量和任务构建
2. 模块是执行实际工作的原子单元,如apt、service、copy等
3. 变量使配置更灵活,可通过多种方式定义
4. 条件和循环提供执行流程控制
5. 模板实现动态配置文件生成
6. 角色是组织复杂配置的最佳实践
7. 错误处理和调试机制确保可靠性
8. 标签和动态包含提供执行灵活性
掌握这些技术后,您可以构建高效、可维护的自动化配置管理解决方案。随着经验的积累,可以进一步探索Ansible的高级特性如异步任务、策略文件和动态清单等,以应对更复杂的自动化场景。





