patternMinor
Combine Lists of Objects in Ansible
Viewed 0 times
objectsansiblecombinelists
Problem
I'm really trying to merge lists of objects along with defaults so I can loop over them and create resources in kubernetes. I've gotten it down to a simple(ish) playbook and will post it here.
The output is as follows...
```
PLAY [localhost] *****
TASK [Gathering Facts] ***
ok: [localhost]
TASK [Set the Things Facts] *
- hosts: localhost
vars:
default_thing_1: 123
default_thing_2: 456
default_transport: train
list_of_things:
- name: foo
common_thing_1: "sam"
- name: bar
common_thing_1: "sam"
common_thing_2: "ham"
- name: biz
common_thing_1: "eggs"
tasks:
- name: Set the Things Facts
set_fact:
thing:
i_am: "{{ item.common_thing_1 | default(default_thing_1) }}"
eggs_ham: "{{ item.common_thing_2 | default(default_thing_2) }}"
loop: "{{ list_of_things }}"
register: things_fact_results
- name: Set Optional Things Facts
set_fact:
thing:
transport: "{{ item.transport | default(default_transport) }}"
when: "item.common_thing_2 is defined and item.common_thing_2 == 'ham'"
loop: "{{ list_of_things }}"
register: transport_fact_results
- name: Debug the Facts
debug:
msg: "{{ item.0 | combine(item.1|default({})) }}"
loop: "{{
things_fact_results.results |
map(attribute='ansible_facts.thing') | list |
zip(
transport_fact_results.results |
map(attribute='ansible_facts.thing') | list
) | list
}}"The output is as follows...
```
PLAY [localhost] *****
TASK [Gathering Facts] ***
ok: [localhost]
TASK [Set the Things Facts] *
Solution
loop requires a valid list. But we got here is,[({'i_am': 'sam', 'eggs_ham': '456'}, AnsibleUndefined),
({'i_am': 'sam', 'eggs_ham': 'ham'}, {'transport': 'train'}),
({'i_am': 'eggs', 'eggs_ham': '456'}, AnsibleUndefined)]
Since no value is assigned to
transport_fact_results when common_thing_2 is not defined.if you remove the
when condition it will work.CODE:
- hosts: localhost
vars:
default_thing_1: 123
default_thing_2: 456
default_transport: train
list_of_things:
- name: foo
common_thing_1: "sam"
- name: bar
common_thing_1: "sam"
common_thing_2: "ham"
- name: biz
common_thing_1: "eggs"
tasks:
- name: Set the Things Facts
set_fact:
thing:
i_am: "{{ item.common_thing_1 | default(default_thing_1) }}"
eggs_ham: "{{ item.common_thing_2 | default(default_thing_2) }}"
loop: "{{ list_of_things }}"
register: things_fact_results
- name: Set Optional Things Facts
set_fact:
thing:
transport: "{{ item.transport | default(default_transport) }}"
when: "item.common_thing_2 is defined and item.common_thing_2 == 'ham'"
loop: "{{ list_of_things }}"
register: transport_fact_results
- name: Debug the Facts
debug:
msg: "{{ item.0 | combine(item.1|default({})) }}"
loop: "{{
things_fact_results.results |
map(attribute='ansible_facts.thing') | list |
zip(
transport_fact_results.results |
map(attribute='ansible_facts.thing') | list
) | list
}}"OUTPUT:
PLAY [localhost] ************************************************************************************************************************************************************************************************
TASK [Gathering Facts] ******************************************************************************************************************************************************************************************
ok: [localhost]
TASK [Set the Things Facts] *************************************************************************************************************************************************************************************
ok: [localhost] => (item={u'common_thing_1': u'sam', u'name': u'foo'})
ok: [localhost] => (item={u'common_thing_1': u'sam', u'common_thing_2': u'ham', u'name': u'bar'})
ok: [localhost] => (item={u'common_thing_1': u'eggs', u'name': u'biz'})
TASK [Set Optional Things Facts] ********************************************************************************************************************************************************************************
ok: [localhost] => (item={u'common_thing_1': u'sam', u'name': u'foo'})
ok: [localhost] => (item={u'common_thing_1': u'sam', u'common_thing_2': u'ham', u'name': u'bar'})
ok: [localhost] => (item={u'common_thing_1': u'eggs', u'name': u'biz'})
TASK [Debug the Facts] ******************************************************************************************************************************************************************************************
ok: [localhost] => (item=[{u'eggs_ham': u'456', u'i_am': u'sam'}, {u'transport': u'train'}]) => {
"msg": {
"eggs_ham": "456",
"i_am": "sam",
"transport": "train"
}
}
ok: [localhost] => (item=[{u'eggs_ham': u'ham', u'i_am': u'sam'}, {u'transport': u'train'}]) => {
"msg": {
"eggs_ham": "ham",
"i_am": "sam",
"transport": "train"
}
}
ok: [localhost] => (item=[{u'eggs_ham': u'456', u'i_am': u'eggs'}, {u'transport': u'train'}]) => {
"msg": {
"eggs_ham": "456",
"i_am": "eggs",
"transport": "train"
}
}
PLAY RECAP ******************************************************************************************************************************************************************************************************
localhost : ok=4 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0Code Snippets
- hosts: localhost
vars:
default_thing_1: 123
default_thing_2: 456
default_transport: train
list_of_things:
- name: foo
common_thing_1: "sam"
- name: bar
common_thing_1: "sam"
common_thing_2: "ham"
- name: biz
common_thing_1: "eggs"
tasks:
- name: Set the Things Facts
set_fact:
thing:
i_am: "{{ item.common_thing_1 | default(default_thing_1) }}"
eggs_ham: "{{ item.common_thing_2 | default(default_thing_2) }}"
loop: "{{ list_of_things }}"
register: things_fact_results
- name: Set Optional Things Facts
set_fact:
thing:
transport: "{{ item.transport | default(default_transport) }}"
when: "item.common_thing_2 is defined and item.common_thing_2 == 'ham'"
loop: "{{ list_of_things }}"
register: transport_fact_results
- name: Debug the Facts
debug:
msg: "{{ item.0 | combine(item.1|default({})) }}"
loop: "{{
things_fact_results.results |
map(attribute='ansible_facts.thing') | list |
zip(
transport_fact_results.results |
map(attribute='ansible_facts.thing') | list
) | list
}}"PLAY [localhost] ************************************************************************************************************************************************************************************************
TASK [Gathering Facts] ******************************************************************************************************************************************************************************************
ok: [localhost]
TASK [Set the Things Facts] *************************************************************************************************************************************************************************************
ok: [localhost] => (item={u'common_thing_1': u'sam', u'name': u'foo'})
ok: [localhost] => (item={u'common_thing_1': u'sam', u'common_thing_2': u'ham', u'name': u'bar'})
ok: [localhost] => (item={u'common_thing_1': u'eggs', u'name': u'biz'})
TASK [Set Optional Things Facts] ********************************************************************************************************************************************************************************
ok: [localhost] => (item={u'common_thing_1': u'sam', u'name': u'foo'})
ok: [localhost] => (item={u'common_thing_1': u'sam', u'common_thing_2': u'ham', u'name': u'bar'})
ok: [localhost] => (item={u'common_thing_1': u'eggs', u'name': u'biz'})
TASK [Debug the Facts] ******************************************************************************************************************************************************************************************
ok: [localhost] => (item=[{u'eggs_ham': u'456', u'i_am': u'sam'}, {u'transport': u'train'}]) => {
"msg": {
"eggs_ham": "456",
"i_am": "sam",
"transport": "train"
}
}
ok: [localhost] => (item=[{u'eggs_ham': u'ham', u'i_am': u'sam'}, {u'transport': u'train'}]) => {
"msg": {
"eggs_ham": "ham",
"i_am": "sam",
"transport": "train"
}
}
ok: [localhost] => (item=[{u'eggs_ham': u'456', u'i_am': u'eggs'}, {u'transport': u'train'}]) => {
"msg": {
"eggs_ham": "456",
"i_am": "eggs",
"transport": "train"
}
}
PLAY RECAP ******************************************************************************************************************************************************************************************************
localhost : ok=4 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0Context
StackExchange DevOps Q#11355, answer score: 1
Revisions (0)
No revisions yet.