JMESPath-like expression to traverse Ansible variables

Hello all,

I’m struggling to find a way to use [] inside a query to traverse an Ansible variable.
The content of the variable comes from a JSON file. The error message I get is "_template error while templating string: expected name or number. String: {{ result.root.
.component }}_".

Let’s say the variable (result) contains the following JSON content:

`
{
“root”: {
“DEV”: [
{
“component”: {
“artifactId”: “component-1”,
“version”: “1.0.0”
}
}
],
“STG”: [
{
“component”: {
“artifactId”: “component-2”,
“version”: “1.0.1”
},
“runtimeConf”: {
“artifactId”: “runtime-configuration”,
“version”: “1.0.1”
}
}
]
}
}

`

My Ansible code tries to extract the values of all the “component” attributes as a list, regardless of the external attributes where the “component” attributes are defined (in the example, “DEV” and “STG”). These external attributes are not known beforehand, hence the need for that * in the query.

`
tasks:

  • set_fact:
    component_list: “{{ result.root.*.component }}”

`

The output I expect is:

`

[
  {
    "artifactId": "component-1"
    "version": "1.0.0"
  },
  {
    "artifactId": "component-2",
    "version": "1.0.1"
  }
]

`
That is, a list of all the objects whose attribute was “component” in the input JSON.

I’ve tried to execute the same query on the JMESPath website with the same input and the result is the one I expect. Unfortunately, this is not the case while executing the task with Ansible.

Am I doing something wrong here? Thanks in advance for your help.

Sorry I forgot, I am using Ansible 2.4.2.0 with Python 2.7.12.

You need to use the json_query filter (and install jmespath module on your ansible controller machine) if you want to use JMESPath filtering.

See

http://docs.ansible.com/ansible/latest/playbooks_filters.html#json-query-filter

There’s an example there that looks fairly similar to what you are trying to do.

Hope this helps,

Jon

Hello Jon,

Thanks for your answer.
I hoped to be able to do it without json_query (and thus without jmespath), but I don’t think it’s possible.