在 ansible with_items 循环中根据条件跳过某些项目

Skip certain items on condition in ansible with_items loop

是否可以有条件地跳过 Ansible with_items 循环运算符中的某些项目,而不生成额外的步骤?

举个例子:

- name: test task
    command: touch "{{ item.item }}"
    with_items:
      - { item: "1" }
      - { item: "2", when: "test_var is defined" }
      - { item: "3" }

在此任务中,我只想在定义 test_var 时创建文件 2。

when: 对每个项目的任务条件进行评估。所以在这种情况下,你可以这样做:

...
with_items:
- 1
- 2
- 3
when: item != 2 and test_var is defined

另一个答案很接近,但会跳过所有项目!= 2。我认为这不是您想要的。这是我会做的:

- hosts: localhost
  tasks:
  - debug: msg="touch {{item.id}}"
    with_items:
    - { id: 1 }
    - { id: 2 , create: "{{ test_var is defined }}" }
    - { id: 3 }
    when: item.create | default(True) | bool

您想要的是始终创建文件 1 和文件 3,但仅在定义 test_var 时才创建文件 2。如果您使用 ansible 的 when 条件,它适用于完整的任务,而不适用于像这样的单个项目:

- name: test task
  command: touch "{{ item.item }}"
  with_items:
      - { item: "1" }
      - { item: "2" }
      - { item: "3" }
  when: test_var is defined

此任务将检查所有三个订单项 1、2 和 3 的条件。

不过,您可以通过两个简单的任务来实现:

- name: test task
  command: touch "{{ item }}"
  with_items:
      - 1 
      - 3

- name: test task
  command: touch "{{ item }}"
  with_items:
      - 2
  when: test_var is defined

我遇到了类似的问题,我的做法是:

...
with_items:
  - 1
  - 2
  - 3
when: (item != 2) or (item == 2 and test_var is defined)

哪个更简单干净。

我最近 运行 研究了这个问题,none 我找到的答案正是我要找的。我想要一种基于另一个变量有选择地包含 with_item 的方法。 这是我想出的:

- name: Check if file exists
  stat: 
    path: "/{{item}}"
  with_items: 
    - "foo"
    - "bar"
    - "baz"
    - "{% if some_variable == 'special' %}bazinga{% endif %}"
   register: file_stat

- name: List files
  shell: echo "{{item.item | basename}}"
  with_items:
    - "{{file_stat.results}}"
  when: 
    - item.stat | default(false) and item.stat.exists

当以上玩法为运行时,file_stat中的项目列表将只包含bazinga如果 some_variable == 'special'