Bootstrap FreeKB - Ansible - Append elements to a List
Ansible - Append elements to a List

Updated:   |  Ansible articles

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 Buy Me A Coffee



Comments


November 16 2022 by Matalve
Good guide! However, running Ansible 2.13.3, I was unable to add an item to the array using your example (third code box). I had to do it like this: set_fact: fruit: "{{ fruit + ['plum'] }}" Probably something changed with set_fact ?

November 17 2022 by Jeremy (moderator)
Nice, thanks for the tip! I added this example (4th code block).

Add a Comment


Please enter be7de6 in the box below so that we can be sure you are a human.