ansible中的剧本(Playbook)详解之when判断
概述
when 给任务添加执行条件:条件成立才执行任务,不成立直接跳过(状态 skipped)。
使用注意事项:
- when进行判断时,一般与变量一起使用
- when条件与facts变量或register变量一起使用。
- when条件还可以与ansible语句一起使用(判断文件、判断目录,判断是否存在,比较大小)
核心语法:
- name: 任务名称
module: 模块名称
args: 模块参数
when: 条件表达式
when判断的运算符
比较运算符
注意:系统版本是字符串,必须 | int 转数字再对比。
-
==:等于,例如name == zhangsan -
!=:不等于,例如name != zhangsan -
>:大于,例如ansible_memtotal_mb > 2048 -
<:小于,例如ansible_memtotal_mb < 2048 -
>=:大于等于,例如disk_free >= 10240 -
<=:小于等于,例如disk_free <= 10240
逻辑运算符:
- and:且,全部成立才为真,也就是两边都成立才返回true
- or:或,一边成立则为真,也就是有一边返回true则 整体都返回true
- not:取反
成员运算符
- in: 判断元素是否在列表中
- not in:元素不在列表中返回true
Jinja2 测试运算符
- is:判断变量是否存在,值是否为true,字符串处理等等
- is not: 和is一样,只不过是取反
数学运算符
- +,-,*,/,%等
运算符常用条件示例:
- 判断变量是否存在 / 是否有值
# 变量 defined 存在才执行
when: my_var is defined
# 变量不存在才执行
when: my_var is not defined
# 变量不为空、非空字符串
when: my_var | length > 0
# 变量为空
when: my_var | length == 0
# 变量布尔为 true
when: enable_install
# 等价于
when: enable_install == true
- 等于、不等于、大小比较
# 字符串相等
when: os_name == "CentOS"
# 数字相等
when: mem_size == 2048
# 不等于
when: ansible_distribution != "Ubuntu"
# 大于/小于
when: cpu_cores > 2
when: disk_free < 10240
- and和or
# 同时满足:系统是CentOS 且 版本7
when: ansible_distribution == "CentOS" and ansible_distribution_major_version == "7"
# 满足其一:CentOS7 或 Rocky8
when: ansible_distribution == "CentOS" or ansible_distribution == "Rocky"
- 判断循环 item 条件
when 在循环中会对每一条 item 单独判断
- name: 只安装大于100M的包
yum: name="{{ item.name }}" state=present
loop:
- {name: small, size: 20}
- {name: bigpkg, size: 200}
when: item.size > 100
- 注册模块返回结果后判断(register)
执行模块保存输出,根据返回码 / 输出判断
- xxx.rc == 0 命令执行成功
- xxx.stdout 标准输出包含内容
- xxx.stderr 错误输出
- name: 检查端口是否监听
shell: ss -lnp | grep 8080
register: port_check
ignore_errors: true # 命令失败不终止play
# 端口不存在才启动服务
- name: 启动java服务
systemd: name=java state=started
when: port_check.rc != 0
- 多行复杂条件(管道换行)
when: |
ansible_os_family == "RedHat"
and ansible_distribution_major_version | int >= 8
and memory_mb > 4096
- 结合vars变量
vars:
env: prod
tasks:
- name: 生产环境初始化
template: src=prod.conf dest=/etc/app.conf
when: env == "prod"
when判断示例:
- 编写playbook
root@master:/data00/ansible# cat playbook_when.yaml
- name: when使用
hosts: es
vars:
env: prod
tasks:
- name: when使用test1
debug:
msg: "test1"
# 当env等于test时执行
when: env == "test"
- name: when使用test2
debug:
msg: "test2"
# 当env等于prod时执行
when: env == "prod"
- 测试执行
root@master:/data00/ansible# ansible-playbook -C playbook_when.yaml
PLAY [when使用] **************************************************************************************************************************************************************************************************
TASK [Gathering Facts] *******************************************************************************************************************************************************************************************
ok: [10.37.120.9]
TASK [when使用test1] *********************************************************************************************************************************************************************************************
skipping: [10.37.120.9]
TASK [when使用test2] *********************************************************************************************************************************************************************************************
ok: [10.37.120.9] => {
"msg": "test2"
}
PLAY RECAP *******************************************************************************************************************************************************************************************************
10.37.120.9 : ok=2 changed=0 unreachable=0 failed=0 skipped=1 rescued=0 ignored=0
when常见踩坑点
- when 里不能加 {{ }},加了直接报错
- 字符串常量必须加引号 when: env == "prod",数字可不用
- 判断数字时,ansible中的值大多为字符串,避免判断错误,可加上
变量名 | int - 多条件列表写法是 and 关系,不是或
- when 只控制当前 task,不会中断整个 play,只是跳过
- register 变量是字典,取值别写错层级(.stdout/.rc)
- 循环内 when 只能过滤单条 item,无法过滤整个循环列表
- 变量不存在直接判断会报错,需搭配 is defined 保护
本文来自博客园,作者:huangSir-devops,转载请注明原文链接:https://www.cnblogs.com/huangSir-devops/p/21418832,微信Vac6666666,欢迎交流

浙公网安备 33010602011771号