I've been trying to figure out for hours how to do the following with Ansible, and looping through a JSON output.
Let me explain, here is my playbook:
- hosts: myhosts
connection: local
gather_facts: yes
tasks:
- name: set_fact
set_fact:
disk_info: "{{ disks | json_query('[*].{disk_size: disksize}')}}"
- name: print set_fact
debug:
msg: "{{ disk_info }}"
- name: iterate on disk_info one and increase index 1..n
debug:
msg: "{{ item }} {{ my_idx }}"
loop:
- "{{ disk_info }}"
loop_control:
index_var: my_idx
Here is the json output that task - name: print
outputs:
TASK [print] ****************************************************
ok: [hostname1] => {
"msg": [
{
"disk_size": "200"
},
{
"disk_size": "200"
},
{
"disk_size": "200"
}
]
}
ok: [hostname2] => {
"msg": [
{
"disk_size": “300"
}
]
}
ok: [hostname3] => {
"msg": [
{
"disk_size": "250”
}
]
}
ok: [hostname4] => {
"msg": [
{
"disk_size": “500"
},
{
"disk_size": “600”
}
]
}
Here the output I'm getting from my task (- name: iterate on disk_info one and increase index 1..n
)
ok: [hostname1] => (item=[{'disk_size': '200'}, {'disk_size': '200'}, {'disk_size': '200'}]) => {
"msg": "[{'disk_size': '200'}, {'disk_size': '200'}, {'disk_size': '200'}] 0"
}
ok: [hostname2] => (item=[{'disk_size': ‘300'}]) => {
"msg": "[{'disk_size': ‘300'}] 0"
}
ok: [hostname4] => (item=[{'disk_size': ‘500'}, {'disk_size': '600’}]) => {
"msg": "[{'disk_size': ’500'}, {'disk_size': '600’}] 0"
}
Expected output:
Hostname1:
disk_size1: 200
disk_size2: 200
disk_size3: 200
Hostname2:
disk_size1: 300
Hostname3:
disk_size1: 500
disk_size2: 600
The expected output can be something similar but adding the index.
Are you trying to add the index to the structure, or to textual output? To get your expected output, your last task should loop over the list (instead of a list that contains the list) and output the data in that form:
- name: iterate on disk_info one and increase index 1..n
debug:
msg: "disk_size{{ my_idx }}: {{ item.disk_size }}"
loop: "{{ disk_info }}"
loop_control:
index_var: my_idx
Creating a structure is more difficult, but not impossible. I'm going to demonstrate without using json_query
or set_fact
, which should be avoided unless you're doing something that's impossible without them.
- hosts: my_hosts
vars:
# You didn't provide an example of your input structure, so I'm assuming it
# looks something like this.
disks:
- name: foo
disksize: 200
- name: bar
disksize: 200
disk_info: "{{ dict(range(0, disks | length) | map('regex_replace', '^', 'disk_size') | zip(disks | map(attribute='disksize'))) }}"
tasks:
- debug:
msg: "{{ disk_info }}"
Result:
TASK [debug] *******************************************************************
ok: [harmless-ghoul.syslog.x.mail.umich.edu] => {
"msg": {
"disk_size0": 200,
"disk_size1": 200
}
}