Ansible built-in module - with_items

ansible

This is an demo to ansible built-in item, with_items

Before the topic, I want to remind of the yaml basic syntax about list and dictionary.
To create a list in yaml, there are two forms(yaml or an abbreviated form) which are equivalent, and we can write both of those in the yaml file

1
2
3
4
5
6
listName:
- 1
- 2
- 3
//// which is the same as the abbreviated form
listName: [1,2,3]

And it’s the same for dictionary

1
2
3
4
5
6
- firstName: kai
lastName: chu
age: 29
phone: 888888
//// which is the same as the abbreviated form
{firstName: kai, lastName: chu, age: 29, phone: 888888}

Keeping that in mind, it’s easier to understand different usages in different projects, regardless of mixed syntax playbooks written by the DevOps.

The following explaination will be similar as what have been given by the offical examples
If you have clearly understood the offical examples, then you don’t have to go further with this post.

This post gives examples about list of values and list of dictionaries

In an ansible playbook, we can use with_items with a list of values, list of dictionaries or a variable, it can either yaml syntax or in an abbreviated form.

4 forms of using list of values

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
---
- name: >-
Demo ansible build-in withItems with list,
this lookup returns a list of items given to it,
if any of the top level items is also a list it will flatten it,
but it will not recurse
hosts: localhost
connection: local
vars:
list_in_var:
- green
- red
- blue

list_in_var_as_abbreviated_form: [green, red, blue]

tasks:
- name: "[List of items - 01] items defined in the same playbook"
debug:
msg: "An item: {{ item }}"
with_items:
- green
- red
- blue

- name: "[List of items - 02] items defined in a variable"
debug:
msg: "An item: {{ item }}"
with_items: "{{ list_in_var }}"

- name: "[List of items - 03] items in an abbreviated form defined in the same playbook"
debug:
msg: "An item: {{ item }}"
with_items: [green, red, blue]

- name: "[List of items - 04] items in an abbreviated form variable"
debug:
msg: "An item: {{ item }}"
with_items: "{{list_in_var_as_abbreviated_form}}"

The output:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
$ ansible-playbook playbook.yaml 

PLAY [Demo ansible build-in withItems, this lookup returns a list of items given to it, if any of the top level items is also a list it will flatten it, but it will not recurse] ***

TASK [Gathering Facts] *********************************************************
ok: [localhost]

TASK [[List of items - 01] items defined in the same playbook] *****************
ok: [localhost] => (item=green) => {
"msg": "An item: green"
}
ok: [localhost] => (item=red) => {
"msg": "An item: red"
}
ok: [localhost] => (item=blue) => {
"msg": "An item: blue"
}
...

4 forms of using list of dictionaries

There is nothing special for dictionaries compared with list of values. The item will be a dictionary in this case and we can use item.key to access the value.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
---
- name: >-
Demo ansible build-in with_items with list of dictionaries,
this lookup returns a list of items given to it,
if any of the top level items is also a list it will flatten it,
but it will not recurse
hosts: localhost
connection: local
vars:
list_of_dictionaries_in_var:
- name: Green
color: green
- name: Red
color: red
- name: Blue
color: blue

list_of_dictionaries_in_var_as_abbreviated_form:
- {name: Green, color: green}
- {name: Red, color: red}
- {name: Blue, color: blue}

tasks:
- name: "[list of dict items - 01] items defined in the same playbook"
debug:
msg: "An item name: {{ item.name }}, color: {{ item.color }}"
with_items:
- name: Green
color: green
- name: Red
color: red
- name: Blue
color: blue

- name: "[list of dict items - 01] items defined in the same playbook"
debug:
msg: "An item name: {{ item.name }}, color: {{ item.color }}"
with_items:
- { name: Green, color: green }
- { name: Red, color: red }
- { name: Blue, color: blue }

- name: "[List of dict items - 02] items defined in an variable"
debug:
msg: "An item name: {{ item.name }}, color: {{ item.color }}"
with_items: "{{ list_of_dictionaries_in_var }}"

- name: "[List of dict items - 03] items defined in an abbreviated form variable"
debug:
msg: "An item name: {{ item.name }}, color: {{ item.color }}"
with_items: "{{list_of_dictionaries_in_var_as_abbreviated_form}}"

The output:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
$ ansible-playbook playbook-with-items-dict.yaml 

PLAY [Demo ansible build-in with_items with list of dictionaries, this lookup returns a list of items given to it, if any of the top level items is also a list it will flatten it, but it will not recurse] ***

TASK [Gathering Facts] *********************************************************
ok: [localhost]

TASK [[list of dict items - 01] items defined in the same playbook] ************
ok: [localhost] => (item={u'color': u'green', u'name': u'Green'}) => {
"msg": "An item name: Green, color: green"
}
ok: [localhost] => (item={u'color': u'red', u'name': u'Red'}) => {
"msg": "An item name: Red, color: red"
}
ok: [localhost] => (item={u'color': u'blue', u'name': u'Blue'}) => {
"msg": "An item name: Blue, color: blue"
}
...

Summary

I found the module with_items is really useful when it comes to adding a few configurations for a provision. It is much flexible when we put configurations as key values in a variable file, with with_items module in a playbook, we don’t have to change the playbook when we need to add a new item.