ansible的playbook

2885 字
14 分钟
ansible的playbook

一、YAML语法#

1.1 YAML 基本规则#

  • 基本结构:AML 文件后缀通常为.yml.yaml,顶层可以是键值对(映射)数组(序列) 或单个值,支持多层嵌套。

  • 大小写敏感Namename 是两个不同的键。

  • 缩进规则:用空格缩进(禁止使用 Tab 键),缩进数量不固定(通常 2 个空格),但同一层级必须保持一致;

    ​ 缩进层级代表层级关系。

  • 注释:以 # 开头,注释内容不会被执行。

1.1.1 数据类型#

​ 字符串:默认无需引号(含空格需加引号),支持单 / 双引号,双引号支持转义(\n/\t),单引号不转义;

​ 数字:整数、浮点数、科学计数法(如 123、-45.6、7.8e9),直接写;

​ 布尔值:true/false(小写)、yes/no(等价),均可;

​ 空值:null~ 或空行(推荐用null);

​ 日期 / 时间:支持 ISO 格式(如2026-01-292026-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)无需引号,值的类型由写法自动识别;

​ 布尔值falseno等价,trueyes等价。

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

说明:

credentialsoptionsdatabase的子键,通过缩进(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 执行命令#

Terminal window
# 基本执行
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 目录」和「查看磁盘使用情况」两个任务。

Terminal window
# 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_lines

2.3.2 带变量 + 提权的 Playbook#

功能:给 webservers 组的主机安装 Nginx,修改监听端口,启动服务(普通用户提权执行)。

Terminal window
# 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: true

2.3.3 带 Handlers 的 Playbook#

Handlers 是「懒执行」的任务,只有被notify触发时才会执行(适合修改配置后重启服务)。

Terminal window
# 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 针对不同主机 / 组执行不同任务。

Terminal window
# 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=true

2.3.5 风格yaml示例对比#

字典风格:

Terminal window
---
- 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

变量风格:

Terminal window
---
- 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=yes

2.4 使用循环变量多任务的playbook#

2.4.1 核心定义#

参数类型 / 性质核心作用
loop任务级关键字指定循环的数据源(通常是列表、字典列表等),让当前任务按数据源重复执行
item内置循环变量Ansible 自动生成,代表loop列表中当前迭代的元素,仅在循环任务内有效

简单来说:loop告诉 Ansible“要循环多少次、每次用什么数据”,item告诉 Ansible “本次循环该用列表里的哪一个数据”。

2.4.2 具体示例#

install_rsync.yml
- 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语法#

  1. 数据组织形式:JSON 的顶层只能是两种结构 ——对象({})数组([])(单个值如 “hello” 虽部分解析器兼容,但不符合标准语法)。

  2. 键值对规则(仅对象):

    • 键(key)必须用双引号包裹(单引号 / 无引号都不合法);

    • 键和值之间用冒号:分隔;

    • 多个键值对用逗号,分隔,最后一个键值对不能加逗号(尾逗号非法)。

  3. 支持的数据类型

    • 字符串(String):双引号包裹,支持转义字符(\n、\t、”、\ 等);

    • 数字(Number):整数、浮点数、负数、科学计数法(如 123、-45.6、7.8e9);

    • 布尔值(Boolean):仅true/false(小写,区分 Python 的 True/False);

    • 空值(Null):仅null(小写,区分 Python 的 None);

    • 数组(Array):方括号包裹,元素用逗号分隔,元素可以是任意合法 JSON 类型;

    • 对象(Object):大括号包裹,由键值对组成。

  4. 其他限制:标准 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的值是字符串数组,数组元素用逗号分隔,最后一个元素无尾逗号。

文章分享

如果这篇文章对你有帮助,欢迎分享给更多人!

ansible的playbook
https://2233941.xyz/posts/ansible的playbook/
作者
lumifly
发布于
2026-08-04
许可协议
CC BY-NC-SA 4.0
Profile Image of the Author
lumifly
不逐世间万丈星河,自守一隅细碎明光
✨ 今日一言
" 加载中... "
——
公告
欢迎来到我的博客!这是一则示例公告。
音乐
封面

音乐

暂未播放

0:00 0:00
暂无歌词
分类
标签
本年还剩 -- --%
本月还剩 -- --%
本周还剩 -- --%
距离--
--
--
天气预报
站点统计
文章
24
分类
1
标签
15
总字数
136,852
运行时长
0
最后活动
0 天前
站点信息
构建平台
Local
博客版本
Firefly v6.12.1
文章许可
CC BY-NC-SA 4.0

文章目录