Search code examples
ansibleansible-filter

How to combine a key: list-value dict to a list of key:value in Ansible?


I have this dictionary:

{
  "key1": [
    "value1",
    "value2"
  ],
  "key2": [
    "value3"
  ]
}

I'd like to have this result:

[
  {"key1": "value1"},
  {"key1": "value2"},
  {"key2": "value3"}
]

Do you have any idea how to do it?


Solution

  • You can use a combination of the filters dict2items and subelements in order to achieve this.

    Given the playbook:

    - hosts: all
      gather_facts: no
    
      tasks:
        - set_fact: 
            list: "{{ list | default([]) + [{ item.0.key: item.1 }] }}"
          loop: "{{ dict | dict2items | subelements('value') }}"
          vars: 
            dict:
              key1:
                - value1
                - value2
              key2:
                - value3
        
        - debug:
            var: list
    

    This will yield the recap:

    PLAY [all] **********************************************************************************************************
    
    TASK [set_fact] *****************************************************************************************************
    ok: [localhost] => (item=[{'key': 'key1', 'value': ['value1', 'value2']}, 'value1'])
    ok: [localhost] => (item=[{'key': 'key1', 'value': ['value1', 'value2']}, 'value2'])
    ok: [localhost] => (item=[{'key': 'key2', 'value': ['value3']}, 'value3'])
    
    TASK [debug] ********************************************************************************************************
    ok: [localhost] => {
        "list": [
            {
                "key1": "value1"
            },
            {
                "key1": "value2"
            },
            {
                "key2": "value3"
            }
        ]
    }
    
    PLAY RECAP **********************************************************************************************************
    localhost                  : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0