How to append to lists in Ansible

Share on FacebookShare on Google+Tweet about this on TwitterShare on LinkedIn

Since I have found the Ansible documentation to be lacking, and StackOverflow insufficient in this matter, I feel the need to share how you can append to a list using Ansible.

I’ve created a demonstration playbook and published it on GitHub. See: https://github.com/betrcode/ansible-append-list

How to merge two lists together:

- debug: msg="Append list to list, or merge two lists"

- name: Setup two lists to be merged
  set_fact:
    list_one:
      - 1
      - 2
      - 3
    list_two:
      - 4
      - 5
      - 6

- name: Merge the two lists
  set_fact:
    lists_merged: "{{ list_one }} + {{ list_two }}"

- name: Demonstrate merged lists
  debug: var=lists_merged

The output will be:

TASK [debug] *******************************************************************
ok: [localhost] => {
    "msg": "Append list to list, or merge two lists"
}

TASK [Setup two lists to be merged] ********************************************
ok: [localhost]

TASK [Merge the two lists] *****************************************************
ok: [localhost]

TASK [Demonstrate merged lists] ************************************************
ok: [localhost] => {
    "lists_merged": [
        1, 
        2, 
        3, 
        4, 
        5, 
        6
    ]
}

Appending a single item to a list is trickier, especially when it’s a string. Here’s how to do it:


- name: Initialize an empty list for our strings
  set_fact:
    my_strings: []

- name: Setup a string variable
  set_fact:
    my_name: "Max"

- name: Append string to list
  set_fact:
    my_strings: "{{ my_strings }} + [ '{{ my_name }}' ]"

- debug: var=my_strings

- name: Append another item to the list
  set_fact:
    my_strings: "{{ my_strings }} + [ 'Power' ]"

- debug: var=my_strings

The output will be:

TASK [Initialize an empty list for our strings] ********************************
ok: [localhost]

TASK [Setup a string variable] *************************************************
ok: [localhost]

TASK [Append string to list] ***************************************************
ok: [localhost]

TASK [debug] *******************************************************************
ok: [localhost] => {
    "my_strings": [
        "Max"
    ]
}

TASK [Append another item to the list] *****************************************
ok: [localhost]

TASK [debug] *******************************************************************
ok: [localhost] => {
    "my_strings": [
        "Max", 
        "Power"
    ]
}

More examples can be found at https://github.com/betrcode/ansible-append-list. Happy provisioning!

5 Comments

  • 1
    DW
    2017-07-14 - 16:36 | Permalink

    Good stuff. Ansible / jinja’s syntax can be mind boggling at times and this was a real help. Although I found I preferred surrounding the whole expression with {{ }} instead of the individual elements. So for strings:

    – set_fact:
    my_strings: “{{ my_strings + [ my_name ] }}”

    – set_fact:
    my_strings: “{{ my_strings + [ ‘Power’ ] }}”

    This way you know that everything between the {{ }} is jinja so you don’t have to keep mentally switching back and forth between yaml and jinja syntax as you read along the line.

    In case any other readers are wondering, here’s how to append a dict created on-the-fly to a list of dicts:

    – set_fact:
    my_dicts: “{{ my_dicts + [ { ‘name’: ‘fred’, ‘age’: computed_age } ] }}”

    You can put quoted strings or variables as keys and values and the variables will be dereferenced properly. Those variables can even be other lists and dicts if you’re assembling some complex data.

  • 2
    heather
    2017-10-02 - 21:46 | Permalink

    this was very helpful and accurate. thanks!

  • 3
    Hemant
    2017-11-08 - 19:03 | Permalink

    Hello,

    I have list of servers IPS using dynamic json file , How can i execute command say ping to all servers from list …

    blow is sample data from file …

    [{“IP”:”192.168.132.166″},{“IP”:”192.168.132.213″},{“IP”:”192.168.132.6″}]

    • 4
      2017-11-16 - 08:22 | Permalink

      Hi Hemant!

      I don’t have the time to write the code right now, but I see two different approaches.

      Your list of servers from a json file could be viewed as what Ansible would refer to as a “dynamic inventory”. See: http://docs.ansible.com/ansible/latest/intro_dynamic_inventory.html

      The other approach would be to take the json file, parse it into a list, probably using a jinja2 filter, and then iterate on that list using `with_items` and call whatever module you want (like command or ping).

  • 5
    2017-11-16 - 08:41 | Permalink

    Hi again Hemant!

    I decided to try coding it. This is the latter approach above. See: https://github.com/betrcode/ansible-parse-json-and-loop

  • Leave a Reply

    Your email address will not be published. Required fields are marked *