arraysdictionaryansibletransform

How convert a list into list of object in ansible


In my playbook I have a list like this

users:
  - readonly
  - write

and I need to translate it to a list of objects/dictionaries

userDict:
  - {'username': readonly, 'database': admin}
  - {'username': write, 'database': admin}

I know, I can do it with Jinja templates:

userDict: |
  {% set ret = [] %}
  {% for item in users %}
  {%   set _ = ret.append({'username': item, 'database': 'admin'}) %}
  {% endfor %}
  {{ ret }}

But I am looking for a shorter solution with filter, something like this:

userDict: "{{ users | map('map', 'username') | combine({'database': admin}) }}"

Solution

  • There are acutally two questions

    A minimal example could look like

    ---
    - hosts: localhost
      become: false
      gather_facts: false
    
      vars:
    
        users:
          - readonly
          - write
    
      tasks:
    
        - debug:
            msg: |
              {% set ret = [] %}
              {% for item in users %}
              {%   set _ = ret.append({'username': item, 'database': 'admin'}) %}
              {% endfor %}
              {{ ret }}
    
        - name: Create a new list
          debug:
            msg: "{{ item | combine( {'database': 'admin'} ) }}"
          loop: "{{ users | map('community.general.dict_kv', 'username') }}"
          loop_control:
            extended: true
            label: "{{ ansible_loop.index }}"
    
    

    resulting into an output of

    TASK [debug] *****************
    ok: [localhost] =>
      msg:
      - database: admin
        username: readonly
      - database: admin
        username: write
    
    TASK [Create a new list] *****
    ok: [localhost] => (item=1) =>
      msg:
        database: admin
        username: readonly
    ok: [localhost] => (item=2) =>
      msg:
        database: admin
        username: write
    

    So finally one may end up with

        - name: Create a new list
          debug:
            msg: "{{ users | map('community.general.dict_kv', 'username') | map('combine', db_entry) }}"
          vars:
            db_entry: {'database': 'admin'}