I have a cert creation tool that outputs certs like so:
{
"cert": "abc123......",
"id": 10,
"key": "abc123....."
}
The actual cert
and key
attributes are base64 encoded but that's irrelevant to the problem here.
When I run this from ansible and register the output as a variable, it is stored with the double-quotes escaped:
{
"cert_output": {
"changed": true,
"delta": "0:00:00.673537",
"end": "2024-05-14 13:34:45.492559",
"failed": false,
"msg": "",
"rc": 0,
"start": "2024-05-14 13:34:44.819022",
"stderr": "",
"stderr_lines": [],
"stdout": "{\"id\":233370662,\"cert\":\"abc123...\",\"key\":\"abc123...\"}",
}
}
I do not find the way to parse out individual keys.
The two flavour of set_fact
below are not working as intended:
- set_fact:
cert: "{{ cert_output.stdout|from_json|json_query('.cert') }}"
key: "{{ cert_output.stdout|from_json|json_query('.key') }}"
- set_fact:
cert: "{{ cert_output.stdout|json_query('.cert') }}"
key: "{{ cert_output.stdout|json_query('.key') }}"
Ansible error:
FAILED! => {"msg": "JMESPathError in json_query filter plugin:\ninvalid token: Parse error at column 0, token "." (DOT), for expression:\n".cert"\n ^"}
You do not need to use JMESPath for this use case, Ansible is very much JSON capable. As soon as you have a JSON, and not the string representation of a JSON, thanks to your correct usage of the from_json
filter, then you can go back querying the dictionaries attributes with the dot notation:
- set_fact:
cert: "{{ (cert_output.stdout | from_json).cert }}"
key: "{{ (cert_output.stdout | from_json).key }}"
Which results in
ok: [localhost] => changed=false
ansible_facts:
cert: abc123...
key: abc123...
Note: the above output was generated running the playbook with the option -v
, which, amongst other useful information, shows the result of a set_fact
task.
As for your JMESPath queries, accessing a JSON identifier on the "root" node of a JSON is done simply by addressing its key, without any dot, so:
- set_fact:
cert: "{{ cert_output.stdout | from_json | json_query('cert') }}"
key: "{{ cert_output.stdout | from_json | json_query('key') }}"
Would result in the same as above.