Ansible complex when statement - 它的一部分未被评估

Ansible complex when statement - part of it is not evaluated

我对 Ansible 剧本中的 "when" 语句有疑问。 这是任务:

- name: Testing port 80 - 443 - 8443 on server_x
  wait_for: host=server_x port={{item}} timeout=1
  with_items:
    - 80
    - 443
    - 8443
  when: (sg_building == "TIGERY" and sg_marley_environment == "DEV" and sg_building is defined and sg_marley_environment is defined) or (specified_building == "TIGERY" and specified_environment == "DEV" and specified_building is defined and specified_environment is defined)

sg_buildingsg_marley_inventory 在动态清单上定义。

specified_inventoryspecified_environment 是用额外变量定义的(-e 和 ansible-playbook命令)

when 语句的第一部分工作正常(“or”之前的所有内容),但是第二部分只是被跳过(我尝试切换位置并且它确认了)

你知道为什么“or”没有按预期工作吗?

谢谢你的帮助!

避免在复杂的表达式中使用 is defined,因为它实际上不是 Jinja2 测试,而是针对未定义错误的 catch
阅读 this 条评论了解详情。

你可能更幸运:

when: (sg_building | default('') == "TIGERY" and sg_marley_environment | default('') == "DEV") or (specified_building | default('') == "TIGERY" and specified_environment | default('') == "DEV")

刚刚试了一下:

- hosts: bidman
  remote_user: deploy
  tasks:
    - debug: msg="test"
      when: (sg_building == "TIGERY"
         and sg_marley_environment == "DEV"
         and sg_building is defined
         and sg_marley_environment is defined)
       or (specified_building == "TIGERY"
         and specified_environment == "DEV"
         and specified_building is defined
         and specified_environment is defined)

命令行

ansible-playbook test.yml -i hosts/test -e specified_building=TIGERY -e specified_environment=DEV

如果正确设置了额外变量,则执行任务。

你用的是哪个ansible版本?

-- 添加于 2017/05/12

您好,请像这样更改语句的顺序:

- hosts: bidman
  remote_user: deploy
  tasks:
    - debug: msg="test"
      when: (sg_building is defined
         and sg_marley_environment is defined
         and sg_building == "TIGERY"
         and sg_marley_environment == "DEV")
       or (specified_building is defined
         and specified_environment is defined
         and specified_building == "TIGERY"
         and specified_environment == "DEV")

所以 ... if defined 在变量的实际检查之前。 这样就可以了。

与此同时,我找到了另一个解决方案,如果定义了另一个变量,则在剧本的开头设置一个空变量。 然后,我只是在没有 is defined

的情况下进行测试
- name: Set empty SG building vars if specified_building is set
  set_fact: sg_building=""
  when: specified_building is defined

- name: Set empty SG env vars if specified_environment is set
  set_fact: sg_marley_environment""
  when: specified_environment is defined

- name: Set empty specified_building vars if sg_building is set
  set_fact: specified_building=""
  when: sg_building is defined

- name: Set empty specified_environment vars if sg_marley_environment is set
  set_fact: specified_environment=""
  when: sg_marley_environment is defined

- name: Testing port 80 - 443 - 8443 on server_x
  wait_for: host=server_x port={{item}} timeout=1
  with_items:
   - 80
   - 443
   - 8443
  when: (sg_building == "TIGERY" and sg_marley_environment == "DEV") or (specified_building == "TIGERY" and specified_environment == "DEV")

@Konstantin Suvorov:我会试试你的解决方案,因为它看起来更优雅