ansible中的剧本(Playbook)详解之初识剧本、变量使用、循环
概述
剧本(Playbook)是Ansible的配置管理、部署编排语言,使用YAML格式编写,通过一组有序的任务描述,实现对批量主机的自动化操作。
核心作用:将零散的 ad-hoc 命令固化为可复用、顺序执行、带变量 / 判断 / 循环的自动化脚本,实现批量服务器配置、部署、运维。
核心优势:
- 声明式语法:描述"目标状态"而非执行步骤
- 幂等性:多次执行结果一致,不会重复操作
- 可读性强:YAML格式易于理解和维护
- 可复用性:支持角色、变量、模板等复用机制
一个简单的Playbook如下:
- hosts: 指定分组
-- 指定任务
tasks:
- name: 任务一,模块一
模块名:
选项一:
选项二:
执行Playbook命令:ansible-playbook [选项参数] 剧本文件
选项参数说明:
- -i:指定主机文件
- -C:测试执行
- -t:指定tag执行
- --syntax-check:检查playbook语法,不连接远程机器、不执行任务
- --step:每一步手动确认再执行
- -f:并发执行主机数量,默认是5
- --user:指定远程用户,例如--user root
- --skip-tags:指定tag执行
- --list-hosts:列出匹配的主机,不执行任务
第一个ansible playbook
编写playbook
root@master:/data00/ansible# cat playbook-elephant.yaml
# hosts指定所有的主机
- hosts: all
# tasks指定任务模块
tasks:
- name: 【task1】打开冰箱
shell:
cmd: echo 打开冰箱
- name: 【task2】大象放进冰箱
shell:
cmd: echo 大象放进冰箱
- name: 【task3】关闭冰箱
shell:
cmd: echo 关闭冰箱
测试执行
root@master:/data00/ansible# ansible-playbook -C playbook-elephant.yaml
PLAY [all] *******************************************************************************************************************************************************************************************************
TASK [Gathering Facts] *******************************************************************************************************************************************************************************************
ok: [10.37.120.9]
ok: [10.37.99.63]
TASK [【task1】打开冰箱] *****************************************************************************************************************************************************************************************
skipping: [10.37.120.9]
skipping: [10.37.99.63]
TASK [【task2】大象放进冰箱] *************************************************************************************************************************************************************************************
skipping: [10.37.120.9]
skipping: [10.37.99.63]
TASK [【task3】关闭冰箱] *****************************************************************************************************************************************************************************************
skipping: [10.37.120.9]
skipping: [10.37.99.63]
PLAY RECAP *******************************************************************************************************************************************************************************************************
10.37.120.9 : ok=1 changed=0 unreachable=0 failed=0 skipped=3 rescued=0 ignored=0
10.37.99.63 : ok=1 changed=0 unreachable=0 failed=0 skipped=3 rescued=0 ignored=0
实际执行
root@master:/data00/ansible# ansible-playbook playbook-elephant.yaml
PLAY [all] *******************************************************************************************************************************************************************************************************
TASK [Gathering Facts] *******************************************************************************************************************************************************************************************
ok: [10.37.120.9]
ok: [10.37.99.63]
TASK [【task1】打开冰箱] *****************************************************************************************************************************************************************************************
changed: [10.37.120.9]
changed: [10.37.99.63]
TASK [【task2】大象放进冰箱] *************************************************************************************************************************************************************************************
changed: [10.37.120.9]
changed: [10.37.99.63]
TASK [【task3】关闭冰箱] *****************************************************************************************************************************************************************************************
changed: [10.37.120.9]
changed: [10.37.99.63]
PLAY RECAP *******************************************************************************************************************************************************************************************************
10.37.120.9 : ok=4 changed=3 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
10.37.99.63 : ok=4 changed=3 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
ansible playbook中的变量
ansible中的变量有多种类型,根据定义位置的不同,其分类主要为:
- 剧本文件中定义变量:比较常用,仅限于当前的play使用
- 变量文件,根据主机清单分组进行定义变量:如果多个剧本,使用相同的变量
- register变量,注册变量:实现shell脚本中的反引号功能,可以获取命令结果
- inventory主机清单中定义变量:未来可以用于批量修改主机使用,其它很少用了
- 命令行中:几乎不用
- facts变量:一般用于获取主机基本信息:ip,主机名,系统,如果不需要可以关闭,用于加速剧本的执行
变量命名规则:
- 与shell类似,不能以数字开头
- 变量中仅包含_下划线即可,不要包含其它的特殊字符
读取变量使用{{ 变量名 }}
playbook文件中定义变量
playbook文件中直接定义变量,只对当前的playbook生效,使用vars关键字定义,下级直接定义key value的形式。
root@master:/data00/ansible# cat playbook_vars.yaml
- name: 部署nginx
hosts: web
# 定义变量
vars:
# 格式:变量名: 变量值
nginx_version: 1.24
listen_port: 80
info:
author: admin
env: test
tasks:
- debug: msg="版本 {{ listen_port }}"
- debug: msg="端口 {{ listen_port }}"
- debug: msg="作者 {{ info.author }}"
- debug: msg="环境 {{ info.env }}"
测试执行
root@master:/data00/ansible# ansible-playbook -C playbook_vars.yaml
PLAY [部署nginx] *************************************************************************************************************************************************************************************************
TASK [Gathering Facts] *******************************************************************************************************************************************************************************************
ok: [10.37.120.9]
ok: [10.37.99.63]
TASK [debug] *****************************************************************************************************************************************************************************************************
ok: [10.37.99.63] => {
"msg": "版本 80"
}
ok: [10.37.120.9] => {
"msg": "版本 80"
}
TASK [debug] *****************************************************************************************************************************************************************************************************
ok: [10.37.99.63] => {
"msg": "端口 80"
}
ok: [10.37.120.9] => {
"msg": "端口 80"
}
TASK [debug] *****************************************************************************************************************************************************************************************************
ok: [10.37.99.63] => {
"msg": "作者 admin"
}
ok: [10.37.120.9] => {
"msg": "作者 admin"
}
TASK [debug] *****************************************************************************************************************************************************************************************************
ok: [10.37.99.63] => {
"msg": "环境 test"
}
ok: [10.37.120.9] => {
"msg": "环境 test"
}
PLAY RECAP *******************************************************************************************************************************************************************************************************
10.37.120.9 : ok=5 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
10.37.99.63 : ok=5 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
使用变量文件定义
将变量写入到一个yaml文件中,然后在playbook中使用vars_files指定变量文件饮用。vars_files可以引入多个。
示例:
- 定义变量文件
root@master:/data00/ansible# cat vars_nginx.yaml
info:
author: huangsir
env: test
root@master:/data00/ansible# cat vars_nginx_info.yaml
nginx_version: 1.24
listen_port: 80
- playbook文件
root@master:/data00/ansible# cat playbook_vars_files.yaml
- name: 部署nginx
hosts: web
# 引入变量文件
vars_files:
- ./vars_nginx.yaml
- /data00/ansible/vars_nginx_info.yaml
tasks:
- debug: msg="版本 {{ listen_port }}"
- debug: msg="端口 {{ listen_port }}"
- debug: msg="作者 {{ info.author }}"
- debug: msg="环境 {{ info.env }}"
- 测试执行
root@master:/data00/ansible# ansible-playbook -C playbook_vars_files.yaml
PLAY [部署nginx] **************************************************************************************************************************************************
TASK [Gathering Facts] ********************************************************************************************************************************************
ok: [10.37.120.9]
ok: [10.37.99.63]
TASK [debug] ******************************************************************************************************************************************************
ok: [10.37.99.63] => {
"msg": "版本 80"
}
ok: [10.37.120.9] => {
"msg": "版本 80"
}
TASK [debug] ******************************************************************************************************************************************************
ok: [10.37.99.63] => {
"msg": "端口 80"
}
ok: [10.37.120.9] => {
"msg": "端口 80"
}
TASK [debug] ******************************************************************************************************************************************************
ok: [10.37.99.63] => {
"msg": "作者 huangsir"
}
ok: [10.37.120.9] => {
"msg": "作者 huangsir"
}
TASK [debug] ******************************************************************************************************************************************************
ok: [10.37.99.63] => {
"msg": "环境 test"
}
ok: [10.37.120.9] => {
"msg": "环境 test"
}
PLAY RECAP ********************************************************************************************************************************************************
10.37.120.9 : ok=5 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
10.37.99.63 : ok=5 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
主机组变量文件,根据主机组使用变量
在剧本的当前路径下定义目录,/group_vars/组名/vars.yaml
示例:
- 创建变量文件
# 主机组es的变量文件
root@master:/data00/ansible/group# cat group_vars/es/vars.yaml
paas_name: es
paas_port: 9200
# 主机组db的变量文件
root@master:/data00/ansible/group# cat group_vars/db/vars.yaml
paas_name: db
paas_port: 3306
# 所有主机的变量文件
root@master:/data00/ansible/group# cat group_vars/all/vars.yaml
version: 1.1
- 编写playbook文件
root@master:/data00/ansible/group# cat group_vars.yaml
- name: es
hosts: es
tasks:
- debug: msg="版本 {{ version }}"
- debug: msg="name {{ paas_name }}"
- debug: msg="port {{ paas_port }}"
- name: db
hosts: db
tasks:
- debug: msg="版本 {{ version }}"
- debug: msg="name {{ paas_name }}"
- debug: msg="port {{ paas_port }}"
- 整体的目录结构
root@master:/data00/ansible/group# tree
.
├── group_vars
│ ├── all
│ │ └── vars.yaml
│ ├── db
│ │ └── vars.yaml
│ └── es
│ └── vars.yaml
└── group_vars.yaml
- 测试执行
能够发现执行时获取到的变量不一致。
root@master:/data00/ansible/group# ansible-playbook -C group_vars.yaml
PLAY [es] ********************************************************************************************************************************************************************************************************
TASK [Gathering Facts] *******************************************************************************************************************************************************************************************
ok: [10.37.120.9]
TASK [debug] *****************************************************************************************************************************************************************************************************
ok: [10.37.120.9] => {
"msg": "版本 1.1"
}
TASK [debug] *****************************************************************************************************************************************************************************************************
ok: [10.37.120.9] => {
"msg": "name es"
}
TASK [debug] *****************************************************************************************************************************************************************************************************
ok: [10.37.120.9] => {
"msg": "port 9200"
}
PLAY [db] ********************************************************************************************************************************************************************************************************
TASK [Gathering Facts] *******************************************************************************************************************************************************************************************
ok: [10.37.99.63]
TASK [debug] *****************************************************************************************************************************************************************************************************
ok: [10.37.99.63] => {
"msg": "版本 1.1"
}
TASK [debug] *****************************************************************************************************************************************************************************************************
ok: [10.37.99.63] => {
"msg": "name db"
}
TASK [debug] *****************************************************************************************************************************************************************************************************
ok: [10.37.99.63] => {
"msg": "port 3306"
}
PLAY RECAP *******************************************************************************************************************************************************************************************************
10.37.120.9 : ok=4 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
10.37.99.63 : ok=4 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
register变量
register变量本质上就是执行shell,将shell的结果保存到变量中,然后在后续的play中进行使用
示例:
- 变量变量文件
root@master:/data00/ansible# cat playbook_register.yaml
- name: register使用
hosts: es
tasks:
- name: 【注册变量值】
shell:
cmd: hostname -I
# 将上面shell命令获取到的值放到ip变量中,后续的task可以进行使用
register: ip
- name: 【打印变量】
debug:
msg: "{{ ip }}"
- 测试执行
root@master:/data00/ansible# ansible-playbook playbook_register.yaml
PLAY [register使用] **********************************************************************************************************************************************************************************************
TASK [Gathering Facts] *******************************************************************************************************************************************************************************************
ok: [10.37.120.9]
TASK [【注册变量值】] ********************************************************************************************************************************************************************************************
changed: [10.37.120.9]
TASK [【打印变量】] **********************************************************************************************************************************************************************************************
ok: [10.37.120.9] => {
"msg": {
"changed": true,
"cmd": "hostname -I",
"delta": "0:00:00.002309",
"end": "2026-07-13 14:25:06.274953",
"failed": false,
"msg": "",
"rc": 0,
"start": "2026-07-13 14:25:06.272644",
"stderr": "",
"stderr_lines": [],
"stdout": "10.37.120.9 172.17.0.1 100.95.185.192 fdbd:dc01:ff:324:7f74:8dda:726c:4312 ",
"stdout_lines": [
"10.37.120.9 172.17.0.1 100.95.185.192 fdbd:dc01:ff:324:7f74:8dda:726c:4312 "
]
}
}
PLAY RECAP *******************************************************************************************************************************************************************************************************
10.37.120.9 : ok=3 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
facts变量
facts变量相当于ansible中的内置变量,存放被管理机器的基本信息。运行脚本的时候会运行:Gathering Facts task任务,Gathering Facts:ansible收集被管理端基本信息,cpu,内存,磁盘,网络,系统。我们在剧本中使用facts变量,未来如果不用可以关闭gather facts功能,加速剧本运行效果facts变量是setup模块获取的
使用facts变量时playbook文件中需要指定gather_facts: true,如果不需要facts变量时,可以指定gather_facts: false,这样剧本执行会更快
示例:
- 编写playbook文件
root@master:/data00/ansible# cat playbook_facts.yaml
- hosts: es
gather_facts: true
tasks:
- name: facts变量输出到屏幕上
debug:
msg: |
"主机名:{{ ansible_facts.hostname }}"
"ip:{{ ansible_facts.all_ipv4_addresses }}"
"系统名称:{{ ansible_facts.distribution }}"
"系统总内存:{{ ansible_facts.memtotal_mb }}"
"系统可用内存:{{ ansible_facts.memfree_mb }}"
"系统内存情况:{{ ansible_facts.memory_mb }}"
"cpu总数:{{ ansible_facts.processor_vcpus }}"
- 测试执行
root@master:/data00/ansible# ansible-playbook playbook_facts.yaml
PLAY [es] ********************************************************************************************************************************************************************************************************
TASK [Gathering Facts] *******************************************************************************************************************************************************************************************
ok: [10.37.120.9]
TASK [facts变量输出到屏幕上] *************************************************************************************************************************************************************************************
ok: [10.37.120.9] => {
"msg": "\"主机名:node02\"\n\"ip:['10.96.0.10', '10.96.3.191', '10.96.3.164', '10.96.1.170', '10.96.0.1', '172.17.0.1', '100.95.185.192', '10.37.120.9']\"\n\"系统名称:Debian\"\n\"系统总内存:253453\"\n\"系统可用内存:192768\"\n\"系统内存情况:{'real': {'total': 253453, 'used': 60685, 'free': 192768}, 'nocache': {'free': 216556, 'used': 36897}, 'swap': {'total': 0, 'free': 0, 'used': 0, 'cached': 0}}\"\n\"cpu总数:64\"\n"
}
PLAY RECAP *******************************************************************************************************************************************************************************************************
10.37.120.9 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
ansible中常用的facts变量
ansible_all_ipv4_addresses: 仅显示ipv4的信息。
ansible_devices: 仅显示磁盘设备信息。
ansible_distribution: 显示是什么系统,例:centos,suse等。
ansible_distribution_major_version: 显示是系统主版本。
ansible_distribution_version: 仅显示系统版本。
ansible_machine: 显示系统类型,例:32位,还是64位。
ansible_eth0: 仅显示eth0的信息。
ansible_hostname: 仅显示主机名。
ansible_kernel: 仅显示内核版本。
ansible_lvm: 显示lvm相关信息。
ansible_memtotal_mb: 显示系统总内存。
ansible_memfree_mb: 显示可用系统内存。
ansible_memory_mb: 详细显示内存情况。
ansible_swaptotal_mb: 显示总的swap内存。
ansible_swapfree_mb: 显示swap内存的可用内存。
ansible_mounts: 显示系统磁盘挂载情况。
ansible_processor: 显示cpu个数(具体显示每个cpu的型号)。
ansible_processor_vcpus: 显示cpu个数(只显示总的个数)。
ansible-playbook中的循环
playbook中的循环一般用于批量开启服务,重启服务,创建文件、目录、添加用户等使用场景中。
playbook中新版本循环语法使用loop。这里也使用loop讲解。
简单列表的循环
使用loop定义需要遍历的元素,然后取元素时默认使用固定变量item。
示例:
# 编写playbook文件
root@master:/data00/ansible# cat loop.yaml
- name: loop的使用
hosts: db
tasks:
- name: loop的使用
debug:
msg: |
"名称:{{ item }}"
loop:
- nginx
- mysql
- redis
## 测试执行
root@master:/data00/ansible# ansible-playbook loop.yaml
PLAY [loop的使用] ************************************************************************************************************************************************************************************************
TASK [Gathering Facts] *******************************************************************************************************************************************************************************************
ok: [10.37.99.63]
TASK [loop的使用] ************************************************************************************************************************************************************************************************
ok: [10.37.99.63] => (item=nginx) => {
"msg": "\"名称:nginx\"\n"
}
ok: [10.37.99.63] => (item=mysql) => {
"msg": "\"名称:mysql\"\n"
}
ok: [10.37.99.63] => (item=redis) => {
"msg": "\"名称:redis\"\n"
}
循环字典数组
示例:
- 编写play_book文件
root@master:/data00/ansible# cat loop_map.yaml
- name: loop循环字典
hosts: es
tasks:
- name: 创建多个用户
debug:
msg: |
"name: {{ item.name }}"
"uid: {{ item.uid }}"
loop:
- { name: "zhangsan", uid: 1001 }
- { name: "lisi", uid: 1002 }
- 测试执行
root@master:/data00/ansible# ansible-playbook loop_map.yaml
PLAY [loop循环字典] **********************************************************************************************************************************************************************************************
TASK [Gathering Facts] *******************************************************************************************************************************************************************************************
ok: [10.37.120.9]
TASK [创建多个用户] **********************************************************************************************************************************************************************************************
ok: [10.37.120.9] => (item={'name': 'zhangsan', 'uid': 1001}) => {
"msg": "\"name: zhangsan\"\n\"uid: 1001\"\n"
}
ok: [10.37.120.9] => (item={'name': 'lisi', 'uid': 1002}) => {
"msg": "\"name: lisi\"\n\"uid: 1002\"\n"
}
PLAY RECAP *******************************************************************************************************************************************************************************************************
10.37.120.9 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
循环中输出循环下标
如果在循环中输出循环下标的话,需要使用loop_control模块
示例:
root@master:/data00/ansible# cat playbook_loopindex.yaml
- name: loop_index使用
hosts: es
tasks:
- name: loop_index使用
debug:
msg: "序号: {{ idx }} 内容: {{ item }}"
loop: [a, b, c, d]
#定义循环控制,可以控制输出循环下标,变量的变量名等等
loop_control:
index_var: idx
测试执行:
root@master:/data00/ansible# ansible-playbook playbook_loopindex.yaml
PLAY [loop_index使用] ********************************************************************************************************************************************************************************************
TASK [Gathering Facts] *******************************************************************************************************************************************************************************************
ok: [10.37.120.9]
TASK [loop_index使用] ********************************************************************************************************************************************************************************************
ok: [10.37.120.9] => (item=a) => {
"msg": "序号: 0 内容: a"
}
ok: [10.37.120.9] => (item=b) => {
"msg": "序号: 1 内容: b"
}
ok: [10.37.120.9] => (item=c) => {
"msg": "序号: 2 内容: c"
}
ok: [10.37.120.9] => (item=d) => {
"msg": "序号: 3 内容: d"
}
PLAY RECAP *******************************************************************************************************************************************************************************************************
10.37.120.9 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
循环中修改循环变量名,不用默认 item
示例:
- debug:
msg: "{{ user.name }} -- {{ user.uid }}"
loop:
- { name: tom, uid: 2001 }
- { name: jack, uid: 2002 }
loop_control:
# 定义变量名
loop_var: user
循环延迟(每次循环间隔几秒)
示例:
- debug:
msg: "{{ user.name }} -- {{ user.uid }}"
loop:
- { name: tom, uid: 2001 }
- { name: jack, uid: 2002 }
loop_control:
loop_var: user
# 单位秒
pause: 1
本文来自博客园,作者:huangSir-devops,转载请注明原文链接:https://www.cnblogs.com/huangSir-devops/p/21402711,微信Vac6666666,欢迎交流

浙公网安备 33010602011771号