Ansible:when 子句中的多个 and/or 条件
Ansible: Multiple and/or conditionals in when clause
我在 when 语句中尝试使用多个 and/or 条件来决定任务是否需要 运行 时遇到问题。基本上,我正在制作一本剧本来使用安全补丁选项、仅内核补丁和在 var 文件中指定包来进行自动系统补丁。
I 运行 playbook 使用以下命令并通过扩展变量选项 (-e) 定义变量
ansible-playbook site.yml -i inventory --ask-vault -u (username) -e "security=true restart=true" -k -K
默认情况下,剧本将更新系统上除内核之外的每个包,但如果我指定了几个变量中的任何一个,我想跳过该操作。我的代码如下:
- name: Update all packages
yum:
name: "*"
state: latest
exclude: "kernel*"
when: security is not defined or kernel is not defined or specified_packages
is not defined and ansible_os_family == "RedHat"
我尝试了以下所有组合:
when: (ansible_os_family == "RedHat") and (security is defined or kernel is defined or specified_packages is defined)
when: (ansible_os_family == "RedHat") and (security == true or kernel == true or specified_packages == true )
<- 这种情况会抛出一个未定义的错误,因为我每次 运行 剧本
都没有定义所有变量
when: ansible_os_family == "RedHat"
when: security is defined or kernel is defined or specified_packages is defined
注意: 我知道并使用了一个额外的变量,例如 "skip" 来跳过此任务并使用 when 子句 when: ansible_os_family == "RedHat" and skip is not defined
但我更喜欢我的用户不需要使用额外的变量来跳过这个默认操作。
我也没有使用标签,因为我正在收集升级前后的软件包列表以进行比较和最后报告,所以我无法 运行 那些,因为它们是本地操作命令。这就是为什么我使用一个角色,通过扩展变量打开和关闭多个任务。我对任何以更有效的方式重写剧本的建议持开放态度,因为我有点菜鸟。
正如@techraf 在评论中指出的那样,defined
/undefined
是一个令人讨厌的测试...
像这样重构:
when:
- ansible_os_family == "RedHat"
- security|d('') != '' or kernel|d('') != '' or specified_packages|d('') != ''
更新。可重现的例子:
- hosts: localhost
gather_facts: no
tasks:
- debug:
msg: hello
when:
- '"RedHat" == "RedHat"'
- security|d('') != '' or kernel|d('') != '' or specified_packages|d('') != ''
执行:
ansible-playbook -e kernel=true playbook.yml
PLAY [localhost] ***************************************************************
TASK [debug] *******************************************************************
ok: [localhost] => {
"msg": "hello"
}
PLAY RECAP *********************************************************************
localhost : ok=1 changed=0 unreachable=0 failed=0
版本:
$ pip list | grep -iP 'ansible|jinja'
ansible (2.2.1.0)
Jinja2 (2.8)
这个答案太简单了!
以下作品:
when: not (security is defined or kernel is defined or specified_packages is defined) and ansible_os_family == "RedHat"
我在 when 语句中尝试使用多个 and/or 条件来决定任务是否需要 运行 时遇到问题。基本上,我正在制作一本剧本来使用安全补丁选项、仅内核补丁和在 var 文件中指定包来进行自动系统补丁。
I 运行 playbook 使用以下命令并通过扩展变量选项 (-e) 定义变量
ansible-playbook site.yml -i inventory --ask-vault -u (username) -e "security=true restart=true" -k -K
默认情况下,剧本将更新系统上除内核之外的每个包,但如果我指定了几个变量中的任何一个,我想跳过该操作。我的代码如下:
- name: Update all packages
yum:
name: "*"
state: latest
exclude: "kernel*"
when: security is not defined or kernel is not defined or specified_packages
is not defined and ansible_os_family == "RedHat"
我尝试了以下所有组合:
when: (ansible_os_family == "RedHat") and (security is defined or kernel is defined or specified_packages is defined)
when: (ansible_os_family == "RedHat") and (security == true or kernel == true or specified_packages == true )
<- 这种情况会抛出一个未定义的错误,因为我每次 运行 剧本
when: ansible_os_family == "RedHat"
when: security is defined or kernel is defined or specified_packages is defined
注意: 我知道并使用了一个额外的变量,例如 "skip" 来跳过此任务并使用 when 子句 when: ansible_os_family == "RedHat" and skip is not defined
但我更喜欢我的用户不需要使用额外的变量来跳过这个默认操作。
我也没有使用标签,因为我正在收集升级前后的软件包列表以进行比较和最后报告,所以我无法 运行 那些,因为它们是本地操作命令。这就是为什么我使用一个角色,通过扩展变量打开和关闭多个任务。我对任何以更有效的方式重写剧本的建议持开放态度,因为我有点菜鸟。
正如@techraf 在评论中指出的那样,defined
/undefined
是一个令人讨厌的测试...
像这样重构:
when:
- ansible_os_family == "RedHat"
- security|d('') != '' or kernel|d('') != '' or specified_packages|d('') != ''
更新。可重现的例子:
- hosts: localhost
gather_facts: no
tasks:
- debug:
msg: hello
when:
- '"RedHat" == "RedHat"'
- security|d('') != '' or kernel|d('') != '' or specified_packages|d('') != ''
执行:
ansible-playbook -e kernel=true playbook.yml
PLAY [localhost] ***************************************************************
TASK [debug] *******************************************************************
ok: [localhost] => {
"msg": "hello"
}
PLAY RECAP *********************************************************************
localhost : ok=1 changed=0 unreachable=0 failed=0
版本:
$ pip list | grep -iP 'ansible|jinja'
ansible (2.2.1.0)
Jinja2 (2.8)
这个答案太简单了!
以下作品:
when: not (security is defined or kernel is defined or specified_packages is defined) and ansible_os_family == "RedHat"