Пропускать определенные элементы при условии в недоступном цикле with_items

Можно ли пропустить некоторые элементы в операторе цикла Ansible with_items по условию без создания дополнительного шага?

Например:

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

в этой задаче я хочу создать файл 2 только тогда, когда определено test_var.


person m_messiah    schedule 12.05.2016    source источник


Ответы (5)


Другой ответ близок, но все элементы будут пропущены! = 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
person Petro026    schedule 12.05.2016

Условие when: для задачи оценивается для каждого элемента. Итак, в этом случае вы можете просто сделать:

...
with_items:
- 1
- 2
- 3
when: item != 2 and test_var is defined
person nitzmahone    schedule 12.05.2016
comment
вместо этого вы можете захотеть when: (item == 2 and test_var is defined) or item != 2; или он никогда не будет выполняться для других элементов - person guido; 12.05.2016
comment
Хороший момент - вот что я получаю за то, что разорвал это в спешке. ;) - person nitzmahone; 13.05.2016
comment
Вам просто нужно переключить and на or? - person Thomas Böhm; 25.10.2017

У меня была аналогичная проблема, и я сделал следующее:

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

Что проще и чище.

person lonix    schedule 30.08.2019

Вы хотите, чтобы файл 1 и файл 3 всегда создавались, но файл 2 создается только тогда, когда определено test_var. Если вы используете условие ansible, когда оно работает с полной задачей, а не с отдельными элементами, например:

- 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
person Deepali Mittal    schedule 12.05.2016
comment
ваше утверждение о том, что условие, при котором условие работает для всей задачи, а не для отдельных элементов, неверно: условие оценивается индивидуально для каждого элемента. см. docs.ansible.com/ansible/ - person guido; 12.05.2016
comment
Вы меня неправильно поняли, я сам сказал то же самое, что и вы. См. В моем ответе, я также упомянул об этом. Эта задача проверит условие для всех трех элементов строки 1, 2 и 3. В приведенном выше заявлении я имел в виду, что это условие, когда условие будет работать не только для одного элемента, но для всех, что означает для всей задачи. - person Deepali Mittal; 14.05.2016

Недавно я столкнулся с этой проблемой, и ни один из найденных мной ответов не был именно тем, что я искал. Мне нужен был способ выборочно включать 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 == ' особый'

person Kevin Gigiano    schedule 20.10.2020