Ansible:理解复合条件 when 语句

标签 ansible ansible-playbook

考虑下面这个简单的 ansible playbook 和相关输出。为什么
任务 5 执行了吗?这些任务是针对 debian 运行的。任务1
按预期失败。那么,为什么要和它一起
'ansible_lsb.major_release|int < 14' 是真的吗?这个有没有
与运算符优先级有关吗?

-jk

---
- name: These tests run against debian
  hosts: frontend001
  vars:
    - bcbio_dir: /mnt/bcbio
    - is_ubuntu: "'{{ansible_distribution}}' == 'Ubuntu'"
    - is_debian: "'{{ansible_distribution}}' == 'Debian'"
  tasks:
    - name: 1. Expect skip because test is_ubuntu
      debug: msg="ansible distribution - {{ansible_distribution}}, release - {{ansible_distribution_release}}, {{ ansible_lsb.major_release }}"
      when: is_ubuntu 

    - name: 2. Expect to print msg because test is_debian
      debug: msg="ansible distribution - {{ansible_distribution}}, release - {{ansible_distribution_release}}, {{ ansible_lsb.major_release }}"
      when: is_debian

    - name: 3. Expect to print msg because release 7 of wheezy
      debug: msg="ansible distribution - {{ansible_distribution}}, release - {{ansible_distribution_release}}, {{ ansible_lsb.major_release }}"
      when:  ansible_lsb.major_release|int < 14

    - name: 4. Expect to print msg because true and true is true
      debug: msg="ansible distribution - {{ansible_distribution}}, release - {{ansible_distribution_release}}, {{ ansible_lsb.major_release }}"
      when: is_debian and ansible_lsb.major_release|int < 14

    - name: 5. Expect to skip because false and true is false
      debug: msg="ansible distribution - {{ansible_distribution}}, release - {{ansible_distribution_release}}, {{ ansible_lsb.major_release }}"
      when: is_ubuntu and ansible_lsb.major_release|int < 14 


$ ansible-playbook -i ~/.elasticluster/storage/ansible-inventory.jkcluster  zbcbio.yml 

PLAY [These tests run against debian] ***************************************** 

GATHERING FACTS *************************************************************** 
ok: [frontend001]

TASK: [1. Expect skip because test is_ubuntu] ********************************* 
skipping: [frontend001]

TASK: [2. Expect to print msg because test is_debian] ************************* 
ok: [frontend001] => {
    "msg": "ansible distribution - Debian, release - wheezy, 7"
}

TASK: [3. Expect to print msg because release 7 of wheezy] ******************** 
ok: [frontend001] => {
    "msg": "ansible distribution - Debian, release - wheezy, 7"
}

TASK: [4. Expect to print msg because true and true is true] ****************** 
ok: [frontend001] => {
    "msg": "ansible distribution - Debian, release - wheezy, 7"
}

TASK: [5. Expect to skip because false and true is false] ********************* 
ok: [frontend001] => {
    "msg": "ansible distribution - Debian, release - wheezy, 7"
}

PLAY RECAP ******************************************************************** 
frontend001                : ok=5    changed=0    unreachable=0    failed=0   

已编辑 :
列出基于 tedder42 的答案的更改,以防有人在家中跟随。

1) 改变
- is_ubuntu: "'{{ansible_distribution}}' == 'Ubuntu'"


- is_ubuntu: "{{ansible_distribution == 'Ubuntu'}}"

2)改变
when: is_ubuntu and ansible_lsb.major_release|int < 14 


when: is_ubuntu|bool and ansible_lsb.major_release|int < 14 

做到了!

-jk

最佳答案

TLDR:您的变量作为字符串输出,未评估。使用 jinja2 修复评估,然后将 var 过滤为 |bool .

调试

你只缺少一件事来调试这个问题。这是我在本地 OSX 机器上运行的内容:

- name: stackoverflow 26188055
  hosts: local
  vars:
    - bcbio_dir: /mnt/bcbio
    - is_ubuntu: "'{{ansible_distribution}}' == 'Ubuntu'"
    - is_debian: "'{{ansible_distribution}}' == 'Debian'"
  tasks:
    - debug: var=is_ubuntu
    - debug: var=is_debian
    - debug: msg="this shows the conditional passes even though it shouldnt"
      when: is_ubuntu and true

和输出:
TASK: [debug var=is_ubuntu] *************************************************** 
ok: [127.0.0.1] => {
    "is_ubuntu": "'MacOSX' == 'Ubuntu'"
}

TASK: [debug var=is_debian] *************************************************** 
ok: [127.0.0.1] => {
    "is_debian": "'MacOSX' == 'Debian'"
}

TASK: [debug msg="this shows the conditional passes even though it shouldnt"] *** 
ok: [127.0.0.1] => {
    "msg": "this shows the conditional passes even though it shouldnt"
}

评估

据我所知,您无法真正评估为 bool 值。通常这是通过展开变量(将它放在每个“何时”中)来完成的。但是,它可以完成,因为您可以将 bool 值作为字符串,然后将其转换为 bool 值 as hinted on the Variables ansible page (搜索“ bool 值”)。
- name: stackoverflow 26188055
  hosts: local
  vars:
    - bcbio_dir: /mnt/bcbio
    - is_ubuntu: "{{ansible_distribution == 'Ubuntu'}}"
    - is_debian: "{{ansible_distribution == 'Debian'}}"
  tasks:
    - debug: var=is_ubuntu
    - debug: var=is_debian
    - debug: msg="this shows the conditional passes even though it shouldnt"
      when: is_ubuntu|bool and true

这是输出。
TASK: [debug var=is_ubuntu] *************************************************** 
ok: [127.0.0.1] => {
    "is_ubuntu": "False"
}

TASK: [debug var=is_debian] *************************************************** 
ok: [127.0.0.1] => {
    "is_debian": "False"
}

TASK: [debug msg="this shows the conditional passes even though it shouldnt"] *** 
skipping: [127.0.0.1]

版本比较过滤器

请注意,您可能想利用 Ansible's version_compare filter .用法留给读者作为练习。

关于Ansible:理解复合条件 when 语句,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26188055/

相关文章:

ansible - 如何在特定主机: ansible-playbook -i <hostname>,上运行ansible

kubernetes - 无法从 ansible 运行 kubectl

Ansible 列出目录文件(ansible 2.9.10)

ansible - 角色和任务可以存在于同一个剧本中吗?

ansible - 递增变量值时出现 Unicode 错误

Ansible 在变量模板中使用任务返回变量

amazon-web-services - 尝试使用 ansible 更改 EC2 实例的根 volume_size 时出错

amazon-ec2 - 检索 ec2 list 时出现身份验证错误。找到了 AWS_ACCESS_KEY_ID 和 AWS_SECRET_ACCESS_KEY 环境变量,但可能不正确

ansible - 尝试使用 ansible 构建包时找不到命令