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 保护
posted @ 2026-07-14 14:16  huangSir-devops  阅读(8)  评论(0)    收藏  举报
作者:你的名字
出处:你的博客链接
本文版权归作者和博客园共有,欢迎转载,但必须给出原文链接,并保留此段声明,否则保留追究法律责任的权利。