If you are not familar with lists, check out Ansible - Getting Started with Lists.
Let's say you are using the set_fact module to create an list of strings. The debug module can be used to output the entire list, like this.
---
- hosts: localhost
tasks:
- set_fact:
fruit: [ apple, banana, orange, grapes ]
- debug:
var: fruit
...
Which should return the following.
ok: [localhost] => {
"fruit": [
"apple"
"banana",
"orange",
"grapes"
]
}
Here is how you would append another string value to the list.
---
- hosts: localhost
tasks:
- set_fact:
fruit: [ apple, banana, orange, grapes ]
- name: Append 'plum' to the 'fruit' list
set_fact:
fruit: "{{ fruit }} + ['plum']"
- debug:
var: fruit
...
Or like this.
---
- hosts: localhost
tasks:
- set_fact:
fruit: [ apple, banana, orange, grapes ]
- name: Append 'plum' to the 'fruit' list
set_fact:
fruit: "{{ fruit + ['plum'] }}"
- debug:
var: fruit
...
The debug module should now return the following.
ok: [localhost] => {
"fruit": [
"apple"
"banana",
"orange",
"grapes",
"plum"
]
}
Append integers to a list
Let's say you are using the set_facts module to create an list of integers.
- set_fact:
integers:
- 1
- 4
- 3
- 5
Here is how you would append another integer value to the list. Notice in this example the 5 is not wrapped in quotes, so that 5 is an integer, not a string.
- name: Append 5 to the 'integers' list
set_fact:
integers: "{{ integers }} + [ 2 ]"
You may want to then sort the list.
- name: Sort the 'integers' list
set_fact:
integers: "{{ integers | sort }}"
Append files to an list using the find module
Here is an example of how you can append files in the /tmp directory beginning with "foo" to the "files" list using the find module and the regex_findall filter.
---
- hosts: localhost
tasks:
- find:
paths: /tmp
register: out
- set_fact:
files: "{{ out.stdout | regex_findall('foo.*') }}"
...
Here is an example of how you can append files in the /tmp directory to the "files" list using the find module and the with_items parameter.
AVOID TROUBLE
Notice in this example that single quotes are placed around {{ item }}. The single quotes are needed when item contains a string, not an integer.
---
- hosts: localhost
tasks:
- find:
paths: /tmp
register: out
- name: create the empty files list
set_fact:
files: []
- name: Append each 'item' to the 'files' list
set_fact:
files: "{{ files }} + [ '{{ item.path }}' ]"
with_items: "{{ out.files }}"
- debug:
var: files
...
Or, default can be used so that you don't have to have a separate task that creates the empty "files" list. But this has the drawback that you will need to have a when statement to ensure the list variable is defined to prevent the play from failing fatal.
---
- hosts: localhost
tasks:
- find:
paths: /tmp
register: out
- name: Append each 'item' to the 'files' list
set_fact:
files: "{{ files | default([]) + [ item.path ] }}"
with_items: "{{ out.files }}"
- debug:
var: files
- name: include_role my_role
include_role:
name: my_role
with_items: "{{ files }}"
when: files is defined
...
Notice in this example that single quotes are not placed around item. Single quotes must not be used when {{ item }} contains an integer.
- name: Append each 'item' to the 'integers' list
set_fact:
integers: "{{ integers }} + [ {{ item }} ]"
with_items: "{{ out.stdout }}"
Append files to an list using the lookup plugin
The lookup plugin and with_items parameter can be used to append each line in a file on the control node to a list. In this example, each line in the foo.txt file on the control node will be appended to the 'lines' list.
---
- hosts: localhost
tasks:
- name: append each line in foo.txt to the 'lines' list
set_fact:
lines: "{{ lines }} + [ '{{ item }}' ]"
with_items: "{{lookup('file', 'foo.txt') }}"
...
Do not name your list "groups"
I once made the mistake of naming my list "groups".
---
- hosts: localhost
tasks:
- name: append groups to the 'groups' list
set_fact:
groups: "{{ groups | default([]) + [ item ] }}"
with_items: "{{ my_groups }}"
- debug:
var: group
...
Which returned the following.
ok: [localhost] => {
"groups": {
"all": [],
"ungrouped": []
}
}
groups is a reserved keyword in Ansible, thus I just had to change the name of my list from "groups" to something else, such as "active_directory_groups".
---
- hosts: localhost
tasks:
- name: append groups to the 'active_directory_groups' list
set_fact:
active_directory_groups: "{{ active_directory_groups | default([]) + [ item ] }}"
with_items: "{{ my_groups }}"
- debug:
var: active_directory_groups
...
And here is an example of how you can loop through a dictionary, append the value of the "name" key to "list" and append "before_" and "_after".
---
- hosts: localhost
vars:
names:
- { name: 'john.doe' }
- { name: 'jane.doe' }
- { name: 'jack.doe' }
- { name: 'joan.doe' }
tasks:
- name: create empty list
set_fact:
list: []
- name: append to list
set_fact:
list: "{{ list + ['before_'+item.value+'_after'] }}"
with_dict: "{{ names }}"
- debug:
var: list
...
Which should return the following.
ok: [localhost] => {
"list": [
"before_john.doe_after",
"before_jane.doe_after",
"before_jack.doe_after",
"before_joan.doe_after"
]
}
Did you find this article helpful?
If so, consider buying me a coffee over at