I’m having a problem when trying to append a dict to a list in Ansible.
My code:
- name: Initialize list for numbers
ansible.builtin.set_fact:
numbers: [123, 456, 789]
- name: Initialize list of objects
ansible.builtin.set_fact:
resources: []
- name: Initialize object
ansible.builtin.set_fact:
resource: {}
- name: Creating object for reference
ansible.builtin.set_fact:
resource:
- projectRef:
external: 'projects/{{ item }}'
resources: "{{ resources + [ resource ] }}"
loop: "{{ numbers }}"
And the output looks like so:
[
{},
[
{
'projectRef': {
'external': 'projects/123'
}
}
],
[
{
'projectRef': {
'external': 'projects/456'
}
}
]
]
The first issue is that it omits the first value in the numbers list. Moreover I was expecting the output to be a list of dicts, not a list of lists. More like so:
[
{
'projectRef': {
'external': 'projects/123'
}
},
{
'projectRef': {
'external': 'projects/456'
}
},
{
'projectRef': {
'external': 'projects/789'
}
}
]
It is simpler to declare the list
resources: "{{ ['project']|product(numbers)|map('join', "https://stackoverflow.com/")|
map('community.general.dict_kv', 'external')|
map('community.general.dict_kv', 'projectRef') }}"
gives what you want
resources:
- projectRef:
external: project/123
- projectRef:
external: project/456
- projectRef:
external: project/789
Optionally, you can use Jinja. The below declaration gives the same result
resources: |
[{% for i in numbers %}
{"projectRef": {"external": "projects/{{ i }}"}},
{% endfor %}]
Example of a complete playbook for testing
- hosts: all
vars:
numbers: [123, 456, 789]
resource1: "{{ ['project']|product(numbers)|map('join', "https://stackoverflow.com/")|
map('community.general.dict_kv', 'external')|
map('community.general.dict_kv', 'projectRef') }}"
resource2: |
[{% for i in numbers %}
{"projectRef": {"external": "projects/{{ i }}"}},
{% endfor %}]
tasks:
- debug:
var: resource1
- debug:
var: resource1.1.projectRef.external
- debug:
var: resource2
- debug:
var: resource2.1.projectRef.external