JScott
JScott

Reputation: 148

Building List of JSON Objects in Ansible

Forgive the possible duplicate, but I also asked this question here, but asking on SO for increased visibility.

I'm trying to build an array/list of JSON objects in Ansible. My playbook is called by specifying --extra-vars "userids=123456,654321".

I then try to build the list with the following. ("TBD" is just a place-holder. I will fill those values with data retrieved from SQL queries later in the playbook)

- name: Initiate User List
      set_fact:
        all_users: []    

    - name: Add new JSON Objects to List
      set_fact:
        all_users: "{{ all_users+ [{ 'UserID': '{{ item }}', 'UserType': 'TBD', 'UserName': 'TBD' }] }}"
      loop: "{{ userids.split(',') }}"

    - name: Debug
      debug:
        var: all_users

The list sort of builds, but it is skipping the first item in the list, and having "{{ item }}" instead. This is the resulting output:

TASK [Initiate User List] *************************************************************************************************************************************************************
ok: [localhost]

TASK [Add new JSON Objects to List] ******************************************************************************************************************************************************
ok: [localhost] => (item=123456)
ok: [localhost] => (item=654321)

TASK [Debug] *****************************************************************************************************************************************************************************
ok: [localhost] => {
    "all_users": [
        {
            "UserID": "654321",
            "UserType": "TBD",
            "UserName": "TBD"
        },
        {
            "UserID": "{{ item }}",
            "UserType": "TBD",
            "UserName": "TBD"
        }
    ]
}

I'm not sure what I'm missing. I tried doing a "set_fact" before the looping task to perform the split() first, but that didn't help. I also tried "with_items" instead of loop, no luck

Upvotes: 1

Views: 3089

Answers (2)

JScott
JScott

Reputation: 148

Thanks for the feedback mdaniel, I ended learning I needed to remove the extra {{ }} as well as the single quotes around item. I had removed either of them when trouble-shooting, but not both at the same time

- name: Initiate User List
      set_fact:
        all_users: []    

    - name: Add new JSON Objects to List
      set_fact:
        all_users: "{{ all_users+ 
               [
                   { 'UserID': item, 
                     'UserType': 'TBD', 
                     'UserName': 'TBD' 
                   }
               ] 
            }}"
      loop: "{{ userids.split(',') }}"

Upvotes: 2

mdaniel
mdaniel

Reputation: 33231

This comes up so often it is a FAQ; don't put nested jinja2 templates in a jijna2 template -- they're python variables so you can use them as such. Using set_fact: with loop: or with_items: is almost never what you want to do

- set_fact:
    all_users: >-
       {%- set results = [] -%}
       {%- for u in userids.split(',') -%}
       {%- set _ = results.append({
         'UserID': u,
         'UserType': u_type,
         'UserName': u_name,
       }) -%}
       {%- endfor -%}
       {{ results }}
  vars:
    u_type: TBD
    u_name: TBD

Upvotes: 1

Related Questions