ansible的playbook
一、YAML语法
1.1 YAML 基本规则
-
基本结构:AML 文件后缀通常为
.yml或.yaml,顶层可以是键值对(映射)、数组(序列) 或单个值,支持多层嵌套。 -
大小写敏感:
Name和name是两个不同的键。 -
缩进规则:用空格缩进(禁止使用 Tab 键),缩进数量不固定(通常 2 个空格),但同一层级必须保持一致;
缩进层级代表层级关系。
-
注释:以
#开头,注释内容不会被执行。
1.1.1 数据类型
字符串:默认无需引号(含空格需加引号),支持单 / 双引号,双引号支持转义(\n/\t),单引号不转义;
数字:整数、浮点数、科学计数法(如 123、-45.6、7.8e9),直接写;
布尔值:true/false(小写)、yes/no(等价),均可;
空值:null、~ 或空行(推荐用null);
日期 / 时间:支持 ISO 格式(如2026-01-29、2026-01-29T10:30:00+08:00),会被解析为日期类型;
数组 / 列表:用-(短横线 + 空格)表示列表项,同一层级的-对齐;
映射 / 对象:键值对用:(冒号 + 空格)分隔,键无需引号(除非含特殊字符)。
1.2 YAML 核心数据结构
| 结构类型 | 语法特征 | 示例 |
|---|---|---|
| 键值对 | 键: 值(冒号后必须加 1 个空格) | web_server: nginx``port: 8080 |
| 列表 | 每行以 - 开头(横杠后加 1 个空格) | - nginx``- mysql``- redis |
| 嵌套结构 | 通过缩进体现层级 | server:`` name: nginx`` port: 80`` enabled: true |
1.3 YAML 特殊值
- 多行文本:用
|(保留换行)或>(折叠换行),适合写脚本 / 配置内容: - 支持锚点(
&)和引用(*)、多行字符串、合并键等语法
# | 保留换行(原样输出)script: | echo "hello ansible" ls -l /tmp# > 折叠换行(合并为一行)desc: > 这是一段 多行的描述 会被折叠成一行1.4 yaml示例
1.4.1 基础示例
# 这是单行注释(应用基础配置)app_name: "用户管理系统" # 字符串加双引号(可选)version: 1.0.2 # 数字(无需引号)port: 8080 # 整数debug: false # 布尔值(等价于 no)timeout: 30.5 # 浮点数empty_value: null # 空值(也可写 ~)create_time: 2026-01-29 # 日期类型说明:
#后的内容是注释,不会被解析; 键(如
app_name)无需引号,值的类型由写法自动识别; 布尔值
false和no等价,true和yes等价。
1.4.2 层级嵌套结构
database: type: mysql host: 127.0.0.1 port: 3306 credentials: # 嵌套的映射 username: root password: 123456 db_name: user_db options: # 嵌套的映射+列表 charset: utf8mb4 connect_timeout: 10 allow_multi_queries: yes说明:
credentials和options是database的子键,通过缩进(2 个空格)体现层级; 嵌套层级无数量限制,只要缩进一致即可。
1.4.3 数组列表
# 简单列表(字符串)allow_ips: - 192.168.1.1 - 192.168.1.2 - 10.0.0.0/8
# 列表嵌套映射(常用!)users: - name: 张三 age: 25 is_admin: true hobbies: [篮球, 游泳] # 行内列表(简写形式,等价于- 篮球\n- 游泳) - name: 李四 age: 30 is_admin: false hobbies: - 读书 - 旅行说明:
列表项以
-开头,同一列表的-必须对齐; 行内列表用
[]包裹(类似 JSON),适合短列表,和分行-等价。
1.4.4 多行字符串
# 写法1:| 保留换行和末尾空行(适合需要严格换行的文本,如代码、日志)multi_line_text1: | 第一行内容 第二行内容 第三行内容(末尾换行保留)
# 写法2:> 折叠换行(将换行转为空格,适合段落文本)multi_line_text2: > 这是一段很长的文本, 希望在YAML中分行写, 但解析后会合并为一行(换行变空格)
# 写法3:单/双引号(转义差异)string_escape1: "Hello\nWorld" # 双引号:\n 会被解析为换行string_escape2: 'Hello\nWorld' # 单引号:\n 原样保留,不转义1.4.5 锚点与引用
# 定义锚点(&common_config)common_config: &common_config timeout: 30 retry: 3 log_level: info
# 引用锚点(*common_config)service1: name: 用户服务 <<: *common_config # 合并锚点的所有键值对 port: 8081
service2: name: 订单服务 <<: *common_config # 复用相同配置 port: 8082 retry: 5 # 覆盖锚点的retry值说明:
&锚点名定义可复用的片段;
<<: *锚点名表示 “将锚点的键值对合并到当前层级”; 引用后可覆盖锚点的字段(如 service2 的
retry: 5)。
二、Ansible Playbook 核心用法
Playbook(剧本)是 Ansible 的「任务编排文件」,由一个或多个「Play」组成,每个 Play 定义:对哪些主机执行哪些任务。
2.1 Playbook 核心元素
| 元素 | 作用 | 示例 |
|---|---|---|
hosts | 指定目标主机 / 主机组(来自 inventory) | hosts: webservers(执行给 webservers 组)hosts: all(执行给所有主机) |
tasks | 任务列表(按顺序执行),每个任务调用 Ansible 模块 | tasks:`` - name: 安装nginx`` yum: name=nginx state=present |
remote_user | 远程执行任务的用户 | remote_user: root |
become | 是否提权(比如普通用户提权到 root) | become: true(开启提权)become_method: sudo(提权方式,默认 sudo) |
vars | 定义变量(可在任务中引用) | vars:`` nginx_port: 80`` pkg_name: nginx |
handlers | 「触发式任务」(仅被 notify 调用时执行),常用于重启服务 | handlers:`` - name: 重启nginx`` service: name=nginx state=restarted |
notify | 触发 handlers 中的任务(任务执行成功后触发) | 在 tasks 中加:notify: 重启ngin |
2.2 playbook 执行命令
# 基本执行ansible-playbook your_playbook.yml
# 常用选项ansible-playbook your_playbook.yml \ --check # 只检查语法/执行计划,不实际执行(干跑验证,不会真正执行) --limit web01 # 仅执行给web01主机(覆盖hosts配置) -v # 详细输出(-vvv 更详细,排错用) -u root # 指定远程用户(覆盖playbook中的remote_user) -i /etc/ansible/hosts # 指定主机清单2.3 playbook使用示例
2.3.1 基础playbook
功能:对所有主机执行「创建 /tmp/test 目录」和「查看磁盘使用情况」两个任务。
# filename: basic_task.yml- name: 基础任务示例(对所有主机执行) hosts: all # 目标主机:所有主机 remote_user: root # 远程执行用户:root tasks: # 任务列表 - name: 创建/tmp/test目录 # 任务名称(可选,但建议写,便于排错) file: # 调用ansible的file模块 path: /tmp/test state: directory # 确保目录存在 mode: '0755' # 目录权限
- name: 查看磁盘使用情况 command: df -h # 调用command模块执行shell命令 register: df_result # 把命令输出保存到df_result变量
- name: 打印磁盘信息 debug: # 调用debug模块输出变量 var: df_result.stdout_lines2.3.2 带变量 + 提权的 Playbook
功能:给 webservers 组的主机安装 Nginx,修改监听端口,启动服务(普通用户提权执行)。
# filename: install_nginx.yml- name: 安装并配置Nginx hosts: webservers # 目标主机:webservers组 remote_user: centos # 普通用户(需有sudo权限) become: true # 开启提权(默认提权到root) become_method: sudo # 提权方式:sudo vars: # 定义变量 nginx_port: 8080 # Nginx监听端口 nginx_conf: /etc/nginx/nginx.conf
tasks: - name: 安装EPEL源(CentOS) yum: name: epel-release state: present
- name: 安装Nginx yum: name: nginx state: present
- name: 修改Nginx监听端口 lineinfile: # 调用lineinfile模块修改配置文件 path: "{{ nginx_conf }}" # 引用变量(用{{ }}) regexp: '^listen\s+80;' # 匹配以listen开头、后跟80的行 line: "listen {{ nginx_port }};" # 替换为变量端口 backup: yes # 修改前备份配置文件
- name: 启动并开机自启Nginx service: name: nginx state: started enabled: true2.3.3 带 Handlers 的 Playbook
Handlers 是「懒执行」的任务,只有被notify触发时才会执行(适合修改配置后重启服务)。
# filename: nginx_with_handler.yml- name: Nginx配置修改+重启(Handlers示例) hosts: webservers remote_user: root vars: nginx_port: 8081
tasks: - name: 修改Nginx监听端口 lineinfile: path: /etc/nginx/nginx.conf regexp: '^listen\s+8080;' line: "listen {{ nginx_port }};" notify: 重启Nginx # 上面任务执行成功后,触发Handlers中的「重启Nginx」
handlers: # 定义Handlers(触发式任务) - name: 重启Nginx service: name: nginx state: restarted只有「修改端口」任务实际修改了配置文件(状态为 changed),才会触发重启;如果配置文件无变化(状态为 ok),则不会重启。
2.3.4 多 Play 的 Playbook
一个 Playbook 可以包含多个 Play,每个 Play 针对不同主机 / 组执行不同任务。
# filename: multi_play.yml# Play1:给webservers组安装Nginx- name: 配置web服务器 hosts: webservers remote_user: root tasks: - name: 安装Nginx yum: name=nginx state=present
# Play2:给dbservers组安装MySQL- name: 配置数据库服务器 hosts: dbservers remote_user: root tasks: - name: 安装MySQL yum: name=mariadb-server state=present - name: 启动MySQL service: name=mariadb state=started enabled=true2.3.5 风格yaml示例对比
字典风格:
---- name: 这是一个安装nginx的剧本 hosts: 172.16.1.7,172.16.1.8,nfs tasks: - name: 01 安装nginx yum: name: nginx # 值之间是以键值对的形式表示的 state: installed - name: 02 启动nginx systemd: name: nginx state: started变量风格:
---- name: 这是一个安装nginx的剧本 hosts: 172.16.1.7,172.16.1.8,nfs tasks: - name: 01 安装nginx yum: name=nginx state=installed #模块下的参数以变量的形式表示 - name: 02 启动nginx systemd: name=nginx state=started - name: 03 设置nginx开机自启 systemd: name=nginx enabled=yes2.4 使用循环变量多任务的playbook
2.4.1 核心定义
| 参数 | 类型 / 性质 | 核心作用 |
|---|---|---|
loop | 任务级关键字 | 指定循环的数据源(通常是列表、字典列表等),让当前任务按数据源重复执行 |
item | 内置循环变量 | Ansible 自动生成,代表loop列表中当前迭代的元素,仅在循环任务内有效 |
简单来说:loop告诉 Ansible“要循环多少次、每次用什么数据”,item告诉 Ansible “本次循环该用列表里的哪一个数据”。
2.4.2 具体示例
- hosts: test vars: user_id: '666' rsync_user: 'www' tasks: # 1.创建www用户和组 - name: 01_create_group group: name: "{{ rsync_user }}" gid: "{{ user_id }}"
# 2.创建www用户 - name: 02_create_user user: name: "{{ rsync_user }}" gid: "{{ user_id }}" group: "{{ rsync_user}}" create_home: no shell: /sbin/nologin
# 3.创建数据目录且授权 - name: 03_createUdata file: path: "{{ item }}" state: direcotry owner: "{{ rsync_user }}" group: "{{ rsync_user}}" mode: "755" loop: - /data - /backup # 4.安装rsync软件 - name: 04_install_rsync yum: name: rsync state: latest # 5.复制配置文件与密码文件 - name: 05_copy_config copy: src: "{{ item.src }}" dest: /etc/ mode: "{{ item.mode }}" notify: - restart_rsyncd loop: - { src:/script/rsyncd.conf,mode:'644'} - { src:/script/rsync.passwd,mode:'600'}
# 6.启动服务 - name: 06_start_rsync systemd: name: rsyncd state: started enabled: yes # 7.重启服务 handlers: - name: restart_rsyncd systemd: name: rsyncd state: restarted三、json语法
-
数据组织形式:JSON 的顶层只能是两种结构 ——
对象({})或数组([])(单个值如 “hello” 虽部分解析器兼容,但不符合标准语法)。 -
键值对规则(仅对象):
-
键(key)必须用双引号包裹(单引号 / 无引号都不合法);
-
键和值之间用冒号
:分隔; -
多个键值对用逗号
,分隔,最后一个键值对不能加逗号(尾逗号非法)。
-
-
支持的数据类型:
-
字符串(String):双引号包裹,支持转义字符(\n、\t、”、\ 等);
-
数字(Number):整数、浮点数、负数、科学计数法(如 123、-45.6、7.8e9);
-
布尔值(Boolean):仅
true/false(小写,区分 Python 的 True/False); -
空值(Null):仅
null(小写,区分 Python 的 None); -
数组(Array):方括号包裹,元素用逗号分隔,元素可以是任意合法 JSON 类型;
-
对象(Object):大括号包裹,由键值对组成。
-
-
其他限制:标准 JSON不支持注释(// 或 /* */),如需注释需使用 JSON5 等扩展格式。
3.1 json示例
3.1.1 基础json对象
{ "name": "张三", "age": 25, "isStudent": false, "score": 98.5, "hobby": null, "address": { "province": "广东省", "city": "深圳市" }}说明:
name是键,必须用双引号;"张三"是字符串值,也必须用双引号;
age的值是数字,无需引号;isStudent是布尔值,小写 false;
address的值是嵌套对象,符合 “对象可以嵌套对象” 的规则。
3.1.2 json数组
[ { "id": 1001, "name": "手机", "price": 2999.99, "tags": ["智能", "5G", "大屏"] }, { "id": 1002, "name": "耳机", "price": 199.0, "tags": ["无线", "降噪"] }]说明:
顶层是数组,包含两个对象元素;
tags的值是字符串数组,数组元素用逗号分隔,最后一个元素无尾逗号。
文章分享
如果这篇文章对你有帮助,欢迎分享给更多人!
赣公网安备36072602000131号