Ansible Playbook
一、Ansible Playbook 核心基础
Playbook 是 Ansible 的自动化脚本文件,基于 YAML 格式,用于批量执行任务。其核心价值是将 “零散命令” 组织成 “可复用、可维护的自动化流程”。
1. Playbook 核心结构
一个完整的 Playbook 由多个Play
组成,每个Play
包含以下关键部分:
组成部分 | 作用说明 |
---|---|
Tasks | 核心执行单元,每个任务调用一个 Ansible 模块(如ping 、yum ),按顺序执行 |
Variables | 存储动态数据,让 Playbook 更灵活(如定义软件名、端口号) |
Templates | 基于 Jinja2 模板生成动态配置文件(如 Apache 的httpd.conf ) |
Handlers | 响应任务变更的 “触发器”(如配置文件修改后重启服务),仅在任务状态为changed 时执行 |
Roles | 将任务、变量、模板等按功能拆分,实现模块化复用(如 “Web 服务角色”“数据库角色”) |
2. 基础 Playbook 示例(含核心语法)
--- # YAML文件标识(可省略)
- name: 部署Web服务 # Play名称(便于识别,可省略)hosts: webservers # 目标主机组(来自/etc/ansible/hosts)remote_user: root # 远程执行用户gather_facts: false # 关闭facts信息收集(加快执行速度,可省略)tasks: # 任务列表# 任务1:测试主机连通性- name: 测试Ping连通性ping: # 调用ping模块(无参数)# 任务2:关闭防火墙(忽略执行错误)- name: 停止firewalld服务service: name=firewalld state=stopped # 模块参数用key=value格式ignore_errors: True # 忽略任务执行失败(如服务已停止)# 任务3:安装Apache(修改配置后触发Handler)- name: 安装httpdyum: name=httpd state=latest- name: 推送httpd配置文件copy: src=/opt/httpd.conf dest=/etc/httpd/conf/httpd.confnotify: "重启httpd" # 配置变更时触发同名Handler# 任务4:启动Apache并设为开机自启- name: 启动httpd服务service: name=httpd state=started enabled=truehandlers: # 触发器列表(仅被notify调用)- name: 重启httpd # 名称必须与notify完全一致service: name=httpd state=restarted
二、Playbook 关键功能与实操
1. 变量使用(灵活传递数据)
变量可通过 “Play 内定义” 或 “命令行传递”,引用时用{{ 变量名 }}
。
方式 1:在 Play 内定义变量
- name: 用变量创建用户和组hosts: dbserversvars: # 定义变量groupname: mysqlusername: nginxtasks:- name: 创建mysql组group: name={{ groupname }} gid=306- name: 创建nginx用户user: name={{ username }} group={{ groupname }}
方式 2:命令行传递变量(优先级更高)
ansible-playbook test.yaml -e "username=testuser" # -e参数指定变量
2. 条件判断(when 指令)
通过when
指定 “任务执行的条件”,条件为true
时才执行任务,变量无需加{{ }}
。
- name: 仅特定IP主机执行关机hosts: alltasks:- name: 重启主机command: /sbin/shutdown -r nowwhen: ansible_default_ipv4.address == "192.168.10.14" # 条件:IP匹配
3. 迭代(循环执行任务)
通过loop
(推荐)或with_items
实现 “重复执行同一任务”,支持列表、字典格式。
- name: 循环创建目录和用户hosts: dbserverstasks:# 1. 循环创建目录(列表格式)- name: 创建/tmp/test1、/tmp/test2file: path={{ item }} state=directoryloop: # 等同于with_items- /tmp/test1- /tmp/test2# 2. 循环创建用户(字典格式)- name: 创建test1、test2用户并指定组user: name={{ item.name }} groups={{ item.groups }}loop:- { name: "test1", groups: "wheel" }- { name: "test2", groups: "root" }
4. Templates 模块(动态生成配置)
基于 Jinja2 模板(后缀.j2
)生成配置文件,支持嵌入变量。
步骤 1:创建 Jinja2 模板(/opt/httpd.conf.j2)
Listen {{ http_port }} # 嵌入变量 ServerName {{ server_name }} DocumentRoot "{{ root_dir }}"
步骤 2:在 Playbook 中使用 Templates 模块
- name: 动态生成httpd配置hosts: webserverstasks:- name: 推送模板并生成配置template: src=/opt/httpd.conf.j2 dest=/etc/httpd/conf/httpd.confnotify: 重启httpd # 配置变更时触发重启
步骤 3:在主机清单中定义变量(/etc/ansible/hosts)
[webservers] 192.168.10.14 http_port=80 server_name=www.test.com root_dir=/var/www/html
5. Tags 模块(指定执行特定任务)
给任务打 “标签”,执行 Playbook 时通过--tags
只运行指定标签的任务,特殊标签always
表示 “始终执行”。
- name: 带标签的任务示例hosts: webserverstasks:- name: 复制hosts文件copy: src=/etc/hosts dest=/opt/hoststags: only # 标签:only- name: 创建测试文件file: path=/opt/test.txt state=touchtags: always # 标签:始终执行
- 执行命令:
ansible-playbook test.yaml --tags="only" # 仅执行标签为only的任务(always任务也会执行)
三、Roles 模块(模块化管理)
Roles 是 Playbook 的 “模块化方案”,将任务、变量、模板等按 “功能” 拆分(如 Web 角色、数据库角色),便于复用和维护。
1. Roles 目录结构(固定格式)
每个角色需按以下目录存放,未用到的目录可省略:
/etc/ansible/roles/ # 默认Roles目录
├── httpd/ # Web服务角色
│ ├── files/ # 存储copy/script模块用到的静态文件
│ ├── templates/ # 存储Jinja2模板文件
│ ├── tasks/ # 任务列表(必须有main.yml)
│ ├── handlers/ # 触发器(必须有main.yml)
│ ├── vars/ # 角色变量(必须有main.yml)
│ ├── defaults/ # 默认变量(优先级最低,必须有main.yml)
│ └── meta/ # 角色依赖、作者等信息(必须有main.yml)
└── mysql/ # 数据库服务角色(结构同上)
2. Roles 实操步骤(以部署 LAMP 为例)
步骤 1:创建 Roles 目录结构
# 创建httpd、mysql、php角色目录
mkdir -p /etc/ansible/roles/{httpd,mysql,php}/{files,templates,tasks,handlers,vars,defaults,meta}
# 创建各角色的main.yml文件(固定文件名)
touch /etc/ansible/roles/{httpd,mysql,php}/{tasks,vars,handlers,defaults,meta}/main.yml
步骤 2:编写各角色的任务与变量
httpd 角色(安装并启动 Apache)
# /etc/ansible/roles/httpd/tasks/main.yml - name: 安装httpdyum: name={{ pkg }} state=latest - name: 启动httpd并设为开机自启service: name={{ svc }} state=started enabled=true# /etc/ansible/roles/httpd/vars/main.yml(角色变量) pkg: httpd svc: httpd
mysql 角色(安装并启动 MariaDB)
# /etc/ansible/roles/mysql/tasks/main.yml - name: 安装MariaDByum: name={{ pkg }} state=latest - name: 启动MariaDBservice: name={{ svc }} state=started enabled=true# /etc/ansible/roles/mysql/vars/main.yml pkg:- mariadb- mariadb-server svc: mariadb
步骤 3:编写总 Playbook(调用 Roles)
创建site.yml
,按主机组分配角色:
# /etc/ansible/site.yml
---
- name: 给Web服务器部署LAMPhosts: webserversremote_user: rootroles: # 调用角色(按顺序执行)- httpd- mysql- php
步骤 4:执行 Roles
cd /etc/ansible
ansible-playbook site.yml # 执行总Playbook
四、Playbook 常用命令
命令用途 | 命令示例 |
---|---|
运行 Playbook | ansible-playbook test.yaml |
检查语法错误 | ansible-playbook test.yaml --syntax-check |
查看任务列表 | ansible-playbook test.yaml --list-task |
查看目标主机 | ansible-playbook test.yaml --list-hosts |
从指定任务开始执行 | ansible-playbook test.yaml --start-at-task='安装httpd' |
输入 SSH 密码执行 | ansible-playbook test.yaml -k |
输入 sudo 密码执行 | ansible-playbook test.yaml -K |