Using item in Ansible json_query

Viewed 929

I'm trying to loop through a list of keys to grab associated names from some json:

- name: show names
  debug:
    msg: "{{ data.json | json_query(query) }}"
  vars:
    query: "[? key==item].name"
  with_items: "{{ keys.split() }}"

But it never displays properly when I try to run it. The keys are correct, but no data is returned:

TASK [get_help_on_SO: show] 
ok: [localhost] => (item=Key1) => {
    "msg": []
}
ok: [localhost] => (item=Key2) => {
    "msg": []
}

Manually putting in the code works just fine so my query syntax seems to be right:

query: "[? key==`Key1`].name"

TASK [get_help_on_SO : show] 
ok: [localhost] => (item=Key1) => {
    "msg": [
        "FooBar 1"
]
}
ok: [localhost] => (item=Key2) => {
    "msg": [
        "FooBar 1"
    ]
}

How can I properly pass the item into the json_query?

2 Answers

You didn't surround the item variable with any Jinja delimiters, so it is not interpreted.
You end testing if the key is equal to the string 'item' and not to the string stored in the variable item.

- name: show names
  debug:
    msg: "{{ data.json | json_query(query) }}"
  vars:
    query: "[?key==`{{ item }}`].name"
  with_items: "{{ keys.split() }}"

Given the data

    keys: 'key1 key3'
    data:
      json: [{
            "key": "key1",
            "name": "name1"
            },
            {
            "key": "key2",
            "name": "name2"
            },
            {
            "key": "key3",
            "name": "name3"
            }
            ]

the expected result is

  - name1
  - name3

It's possible to avoid both the loop and json_query and simplify the solution. The task below

    - name: show names
      debug:
        msg: "{{ data.json|
                 selectattr('key', 'in', my_keys)|
                 map(attribute='name')|
                 list }}"
      vars:
        my_keys: "{{ keys.split() }}"

gives

  msg:
  - name1
  - name3
Related