Search code examples
ansiblejinja2nested-lists

How to Append a combination field into nested list using Jinja2?


Below is sample dataset (Could extract them as a dict if that's easier as I'm using Ansible read_csv)

[
        {
            "id": "1",
            "name": "apple",
            "quantity": "10",
            "type": "fruit"
        },
        {
            "id": "2",
            "name": "orange",
            "quantity": "20",
            "type": "fruit"
        },
        {
            "id": "3",
            "name": "carrot",
            "quantity": "5",
            "type": "veg"
        },
        {
            "id": "4",
            "name": "beetroot",
            "quantity": "2",
            "type": "veg"
        }
]

I needed to append a combination field including type-name-id combo to the nested list So the final outcome expected is

[
        {
            "uid": "fruit-apple-1",
            "id": "1",
            "name": "apple",
            "quantity": "10",
            "type": "fruit"
        },
        {
            "uid": "fruit-orange-2",
            "id": "2",
            "name": "orange",
            "quantity": "20",
            "type": "fruit"
        },
        ...

The list is pretty large and hence avoiding the ansible loop and using plain Jinja. I've tried below, but below pivots into a list of combination field ONLY. But I wanted to retain the nesting rather than a flat list

        - jinja_list: |-
            {% set uid = [] %}
            {% for item in fruits_csv_list.list %}
            {% set li = item.type + '-' +  item.name + '-' +  item.id %}
            {{uid.append(li)}}
            {%- endfor %}
            {{uid}}  

Any idea how to achieve it efficiently?


Solution

  • You just have to combine the current item with the k/v you need for the current uid. In a nutshell:

        jinja_list: |-
          {% set result = [] %}
          {% for item in fruits_csv_list.list %}
          {% set li = {'uid': [item.type, item.name, item.id] | join('-')} %}
          {{ result.append(item | combine(li)) }}
          {%- endfor %}
          {{ result }}