I have a playbook that collects a list of information from multiple hosts, and I want to collect those lists together into a single variable. So for example, my output might look like this:
ok: [ALBSWA052] => {
"myvar": [
"ALBSWA052 exists",
"ALBSWA052 is secondary"
]
}
ok: [ALBSWA051] => {
"myvar": [
"ALBSWA051 exists",
"ALBSWA051 is primary"
]
}
and I'd like to combine them into a list like
"myvar": [
"ALBSWA052 exists",
"ALBSWA052 is secondary"
"ALBSWA051 exists",
"ALBSWA051 is primary"
]
Is there an elegant way to do this? The only way I can think of is to write it into a file and read it back in.
myvar1: "{{ ansible_play_hosts | map('extract', hostvars, 'myvar')
| flatten }}"
gives the expected result
myvar1:
- ALBSWA051 exists
- ALBSWA051 is secondary
- ALBSWA052 exists
- ALBSWA052 is secondary
myvar1: VARIABLE IS NOT DEFINED!
In this case, use json_query. For example,
myvar2: "{{ hostvars | json_query('*.myvar') | flatten }}"
gives, if my_var is missing in ALBSWA052
myvar2:
- ALBSWA051 exists
- ALBSWA051 is secondary
shell> cat hosts
ALBSWA051
ALBSWA052
ALBSWA053
If myvar is defined in ALBSWA053 the former declaration will give
myvar2:
- ALBSWA051 exists
- ALBSWA051 is secondary
- ALBSWA053 exists
- ALBSWA053 is secondary
In this case, select the hostvars
myvar3: "{{ hostvars | dict2items
| selectattr('key', 'in', ansible_play_hosts)
| json_query('[].value.myvar')
| flatten }}"
gives
myvar3:
- ALBSWA051 exists
- ALBSWA051 is secondary
Of course, if myvar is defined in both ALBSWA051 and ALBSWA052 you get the expected result
myvar3:
- ALBSWA051 exists
- ALBSWA051 is secondary
- ALBSWA052 exists
- ALBSWA052 is secondary
Example of a complete playbook for testing
shell> cat pb.yml
- hosts: ALBSWA051,ALBSWA052
gather_facts: false
vars:
myvar1: "{{ ansible_play_hosts | map('extract', hostvars, 'myvar')
| flatten }}"
myvar2: "{{ hostvars | json_query('*.myvar') | flatten }}"
myvar3: "{{ hostvars | dict2items
| selectattr('key', 'in', ansible_play_hosts)
| json_query('[].value.myvar')
| flatten }}"
tasks:
- debug:
var: myvar1
run_once: true
- debug:
var: myvar2
run_once: true
- debug:
var: myvar3
run_once: true
shell> tree .
.
├── ansible.cfg
├── hosts
├── host_vars
│ ├── ALBSWA051.yml
│ ├── ALBSWA052.yml
│ └── ALBSWA053.yml
└── pb.yml
shell> cat host_vars/ALBSWA051.yml
myvar: [ALBSWA051 exists, ALBSWA051 is secondary]
shell> cat host_vars/ALBSWA052.yml
myvar: [ALBSWA052 exists, ALBSWA052 is secondary]
shell> cat host_vars/ALBSWA053.yml
myvar: [ALBSWA053 exists, ALBSWA053 is secondary]