Search code examples
pythonansiblejinja2jmespath

Concatenate result element of JMESpath multiselect filter with a variable


I have following variable structure in Ansible (YAML format):

my_groups:
  - name: g1
    users:
      - name: foo
        param: rock
        junk: whatever

      - name: bar
        param: paper 
        junk: whatever

  - name: g2
    users:
      - name: baz
        param: scissors
        junk: whatever

And I need to transform it to flat array of users that looks like this (note the 1 in each name):

- name: foo1
  param: rock

- name: bar1
  param: paper 

- name: baz1
  param: scissors

I use Jinja filter json_query (which internally use JMESPath query language in Python) like this:

{{ my_groups|json_query( "[*].users[*].{ name: name, param: param }" ) }}

Which returns the array mentioned above but without the 1 in the name of course. Is there some way how to achieve the desired concatenation with a simple string? I tried some variants due to documentation and examples but with no luck i.e.:

{{ my_groups|json_query( "[*].users[*].{ name: name + '1', param: param }" ) }}

Simple Ansible playbook is available at pastebin


Solution

  • JMESPath has join built-in to convert list into string.

    - debug:
        msg: "{{ my_groups | json_query(qry) }}"
      vars:
        qry: "[*].users[*][].{ name: join('',[name,'1']), param: param }"
    

    Also note [] after users[*] to flatten the list.

    Result:

    "msg": [
        {
            "name": "foo1",
            "param": "rock"
        },
        {
            "name": "bar1",
            "param": "paper"
        },
        {
            "name": "baz1",
            "param": "scissors"
        }
    ]