I have a yml file (cert_expiring.yml) that I'm generating in my playbook and it consists of a dictionary of IDs and server names of servers whose SSL certs are expiring.
Ex: cert_expiring.yml
myDict:
705:node1.corp.com
670:node2.corp.com
1163:node3.corp.com
715:node4.corp.com
I have a play that is reading in this file and storing it inside a variable called "expired_certs":
- name: Store file contents into variable
include_vars:
file: cert_expiring.yml
name: expired_certs
The contents of "expired_certs" looks like this:
{
"msg": {
"changed": true,
"msg": "All items completed",
"results": [{
"ansible_loop_var": "item",
"backup": "",
"changed": true,
"diff": [{
"after": "",
"after_header": "./cert_expiring.txt (content)",
"before": "",
"before_header": "./cert_expiring.txt (content)"
},
{
"after_header": "./cert_expiring.txt (file attributes)",
"before_header": "./cert_expiring.txt (file attributes)"
}
],
"failed": false,
"invocation": {
"module_args": {
"attributes": null,
"backrefs": false,
"backup": false,
"content": null,
"create": true,
"delimiter": null,
"dest": "./cert_expiring.txt",
"directory_mode": null,
"firstmatch": false,
"follow": false,
"force": null,
"group": null,
"insertafter": null,
"insertbefore": null,
"line": " 705:node1.corp.com",
"mode": null,
"owner": null,
"path": "./cert_expiring.txt",
"regexp": null,
"remote_src": null,
"selevel": null,
"serole": null,
"setype": null,
"seuser": null,
"src": null,
"state": "present",
"unsafe_writes": null,
"validate": null
}
},
"item": {
"cn": "node1.corp.com",
"expires": "2020-11-05T15:20:18+00:00",
"id": 705,
"serial": "1111"
},
"msg": "line added"
}]
}
}
I'm trying to follow the same procedure here to reference "cn", "expires", "id", and "serial" from the nested json but not sure why its not working.
This is my play to access those elements:
- name: Print expired_certs variable contents
debug:
msg: "{{ expired_certs | json_query('results.item[*].{expires: expires, cn: cn, serial: serial, id: id}') }}"
Output:
ok: [localhost] => {
"msg": ""
}
Also, tried this:
msg: "{{ expired_certs | json_query('results.[*].{expires: item.expires, cn: item.cn, serial: item.serial, id: itme.id}') }}"
Output:
ok: [localhost] => {
"msg": {
"cn": null,
"expires": null,
"id": null,
"serial": null
}
}
Need help understanding how to access nested elements.
Looking at your JSON, the key results
is a list, not a dictionary:
{
"results": [{
"changed": true,
"...cut": "for brevity"
}]
}
In JSON, square brackets indicate array (or list to speak Ansible language)
And the key item
is a dictionary, not a list:
{
"item": {
"cn": "node1.corp.com",
"expires": "2020-11-05T15:20:18+00:00",
"id": 705,
"serial": "1111"
}
}
In JSON, curly brackets indicate objects (or dictionary to speak Ansible language)
So, your wildcard expression is just laying on the wrong key.
It should be:
results[*].item
As opposed yo your actual:
results.item[*]
And also, because the item
key does already contains only the information you need, you don't need to go the extra mile and redo an object. You can stay with results[*].item
.
Ending up with:
- name: Print expired_certs variable contents
debug:
msg: "{{ expired_certs | json_query('results[*].item') }}"