
The following parameters can be used to loop through each item in an array / list.
- loop
- vars
- with_items (this article)
- with_indexed_items
- with_list
- with_nested
- with_sequence
In this example, the debug module and with_items parameter are used to loop over a list of fruit (a fruit loop!).
The loop parameters will, by default, use the {{ item }} variable for each item in the list. Or, the loop_control parameter with loop_var can be used to define your own variable for each item in the list.
---
- name: main play
hosts: localhost
vars:
fruits:
- apple
- banana
- orange
- grapes
tasks:
- name: loop through the 'fruits' list
debug:
var: item
with_items: "{{ fruits }}"
...
Which should return the following.
ok: [localhost] => (item=apple) => {
"item": "apple"
}
ok: [localhost] => (item=banana) => {
"item": "banana"
}
ok: [localhost] => (item=orange) => {
"item": "orange"
}
ok: [localhost] => (item=grapes) => {
"item": "grapes"
}
with_items vs loop
Be aware that there are differences between the with_items and loop parameters. For example, the following would produce the same output as above.
- name: loop over list items
debug:
var: item
with_items:
- [ apple, banana, orange, grapes ]
However, the loop parameter . . .
- name: loop over list items
debug:
var: item
loop:
- [ apple, banana, orange, grapes ]
would produce the following.
TASK [loop through the 'fruit' array]
ok: [server1.example.com] => (item=['apple', 'banana', 'orange', 'grapes']) => {
"msg": " ['apple', 'banana', 'orange', 'grapes']"
}
Or, sometimes it's OK to include the index number of one of the items in the list.
---
- name: main play
hosts: localhost
vars:
fruits:
- apple
- banana
- orange
- grapes
tasks:
- name: loop through the 'fruits' list
debug:
var: item
with_items: "{{ fruits[0] }}"
...
Or like this, without using with_items.
---
- name: main play
hosts: localhost
vars:
fruits:
- apple
- banana
- orange
- grapes
tasks:
- name: return the item that has index 0 in the fruits list
debug:
var: fruits[0]
...
In this example, fruits[0] is the element in the fruits list that has index 0 (apple).
ok: [localhost] => (item=apple) => {
"ansible_loop_var": "item",
"item": "apple"
}
register parameter
The register parameter is used to store the output of an Ansible module. The output is always returned as a dictionary of key/value pairs. In this example, the dictionary returned by the shell module will be stored in a dictionary named "out".
- name: ps command
ansible.builtin.shell: ps
register: out
For example, the shell module may return the following named dictionary. In this example, the dictionary is in the "out" key.
TASK [ps]
ok: [localhost] => {
"out": {
"changed": true,
"cmd": "ps",
"delta": "0:00:02.674260",
"end": "2021-08-03 23:34:44.388683",
"failed": false,
"failed_when_result": false,
"msg": "non-zero return code",
"rc": 1,
"start": "2021-08-03 23:34:41.714423",
"stderr": "",
"stderr_lines": [],
"stdout": "root 122418 122378 0 23:41 ? 00:00:00 bash",
"stdout_lines": [
"root 122418 122378 0 23:41 ? 00:00:00 bash"
]
}
}
Notice that the stdout_lines and stderr_lines keys in the "out" dictionary are lists. Here is how you could loop through the stdout_lines list.
- ansible.builtin.debug:
var: item
with_items: "{{ out.stdout_lines }}"
Be aware that sometimes register will have JSON that contains the results array. Notice in this example that the results array contains two items, foo and bar.
ok: [localhost] => {
"out": {
"results": [
"stdout": "foo",
"stdout": "bar"
]
]
}
}
In this scenario, you would need to loop through the results array.
- name: loop through the ps command
debug:
var: item.stdout
with_items: "{{ ps.results }}"
key value pairs
In this example, the with_items is used to loop over key value pairs.
---
- hosts: localhost
tasks:
- debug:
msg: "key = {{ item.key }}, value = {{ item.value }}"
with_items:
- { key: 'fruit', value: 'banana' }
- { key: 'fruit', value: 'orange' }
- { key: 'veggy', value: 'onion' }
- { key: 'veggy', value: 'pepper' }
...
Which should return the following.
TASK [loop through the 'food' hash]
ok: [localhost] => (item={u'value': u'banana', u'key': u'fruit'}) => {
"msg": "key = fruit, value = banana"
}
ok: [localhost] => (item={u'value': u'orange', u'key': u'fruit'}) => {
"msg": "key = fruit, value = orange"
}
ok: [localhost] => (item={u'value': u'onion', u'key': u'veggy'}) => {
"msg": "key = veggy, value = onion"
}
ok: [localhost] => (item={u'value': u'pepper', u'key': u'veggy'}) => {
"msg": "key = veggy, value = pepper"
}
As a bit more of a practical example, here is how you could create create multple files and directories using the file module using with_items.
---
- hosts: localhost
tasks:
- name: create multiple files and directories
file:
path: "{{ item.path }}"
state: "{{ item.state }}"
with_items:
- { path: "/tmp/foo", state: "directory" }
- { path: "/tmp/bar", state: "directory" }
- { path: "/tmp/foo/example.txt", state: "touch" }
- { path: "/tmp/bar/example.txt", state: "touch" }
...
Did you find this article helpful?
If so, consider buying me a coffee over at