I am trying to retrieve a value from a JSON in Ansible, where the key contains dashes and is provided via a variable.
I have the following data in Ansible:
- set_fact:
data: >-
{
"profile-id": 1234, "user_id": 6789
}
It is known that to retrieve profile-id
, one has to quote the key, for example:
- set_fact:
value: >-
{{ data | json_query("profile-id") }}
How could I retrieve the value, if profile-id
is registered in a variable?
For example, with the following variable:
- set_fact:
lookup_key: profile-id
I have tried different approaches, none of them working:
json_query("lookup_key")
does not substitute the lookup keyjson_query(\"lookup_key\")
attempts to look up "profile-id"
instead of profile-id
, returning no results.json_query(lookup_key | regex_replace('[-]', '\\-'))
returns the error: Unknown token \\
.How should I handle this?
Mind that your variable data
does contains the string representation of a JSON, and not a JSON.
Since Ansible is very much JSON capable and that YAML is a superset of JSON, your data
fact could benefit from being expressed as a JSON or a YAML:
# expressed as a JSON:
data: {
"profile-id": 1234, "user_id": 6789
}
# or expressed as a YAML:
data:
profile-id: 1234
user_id: 6789
Which would make your task of accessing it trivial:
- set_fact:
value: "{{ data[lookup_key] }}"
vars:
lookup_key: profile-id
Which results in
ok: [localhost] => changed=false
ansible_facts:
value: '1234'
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.
Now, if you do receive a string representation of a JSON from another task or from a API query, then you can use the from_json
filter to parse the string into a real JSON, where
- set_fact:
value: >-
{{ (data | from_json)[lookup_key] }}
vars:
lookup_key: profile-id
data: >-
{ "profile-id": 1234, "user_id": 6789 }
Also results in value
being set to 1234
As for your JMESPath query, you are right that a JSON identifier with dash has to be queried using double quote in the query itself, but that means that the double quote have to be part of the lookup_key
variable!
So, you could use simple quote to delimit the lookup_key
value. Or use the folded syntax again:
# with simple quote:
lookup_key: '"profile-id"'
# with the folded syntax:
lookup_key: >-
"profile-id"
So your tasks could look like:
- set_fact:
value: >-
{{ data | json_query(lookup_key) }}
vars:
lookup_key: >-
"profile-id"
data:
profile-id: 1234
user_id: 6789