Reputation: 2264
Is it possible to skip some items in Ansible with_items
loop operator, on a conditional, without generating an additional step?
Just for example:
- name: test task
command: touch "{{ item.item }}"
with_items:
- { item: "1" }
- { item: "2", when: "test_var is defined" }
- { item: "3" }
in this task I want to create file 2 only when test_var
is defined.
Upvotes: 27
Views: 43320
Reputation: 111
I recently ran into this problem and none of the answers I found were exactly what I was looking for. I wanted a way to selectively include a with_item based on another variable. Here is what I came up with:
- 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
When the above plays are run, the list of items in file_stat will only include bazinga if some_variable == 'special'
Upvotes: 3
Reputation: 20591
I had a similar problem, and what I did was:
...
with_items:
- 1
- 2
- 3
when: (item != 2) or (item == 2 and test_var is defined)
Which is simpler and cleaner.
Upvotes: 8
Reputation: 13940
The when:
conditional on the task is evaluated for each item. So in this case, you can just do:
...
with_items:
- 1
- 2
- 3
when: item != 2 and test_var is defined
Upvotes: 7
Reputation: 1032
What you want is that file 1 and file 3 always gets created but file 2 is created only when test_var
is defined. If you use ansible's when condition it works on complete task and not on individual items like this :
- name: test task
command: touch "{{ item.item }}"
with_items:
- { item: "1" }
- { item: "2" }
- { item: "3" }
when: test_var is defined
This task will check the condition for all three line items 1,2 and 3.
However you can achieve this by two simple tasks :
- name: test task
command: touch "{{ item }}"
with_items:
- 1
- 3
- name: test task
command: touch "{{ item }}"
with_items:
- 2
when: test_var is defined
Upvotes: 0
Reputation: 1309
The other answer is close but will skip all items != 2. I don't think that's what you want. here's what I would do:
- 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
Upvotes: 29