Search code examples
jsonansiblejinja2ansible-2.xansible-template

Duplicate object values while merging the JSON Objects arrays in Ansible


I am trying to merge 2 JSON file Objects. But 2 of the objects are getting appended with the same value in both the JSON file.

Here Month & Year values are same in both JSON file like Month=1 & Year=2023, so its getting appended in the output JSON, how can i avoid this? The expected value in the output is Month=1 & Year=2023 and not Month=11 & Year=20232023.

Input1

{
    "data": [
        {
            "item_value_01": "APPLICATION",
            "quantity": 1
        },
        {
            "item_value_01": "HERBERT",
            "quantity": 1
        }
    ],
    "month": "1",
    "year": "2023"
}

Input2

{
    "data": [
        {
            "item_value_01": "Test",
            "quantity": 1
        },
        {
            "item_value_01": "Country",
            "quantity": 1
        }
    ],
    "month": "1",
    "year": "2023"
}

Wrong Output

{
        "data": [
            {
                "item_value_01": "APPLICATION",
                "quantity": 1
            },
            {
                "item_value_01": "HERBERT",
                "quantity": 1
            },
 
            {
                "item_value_01": "Test",
                "quantity": 1
            },
            {
                "item_value_01": "Country",
                "quantity": 1
            }
        ],
        "month": "11",
        "year": "20232023"
    }

Expected Output

{
        "data": [
            {
                "item_value_01": "APPLICATION",
                "quantity": 1
            },
            {
                "item_value_01": "HERBERT",
                "quantity": 1
            },
 
            {
                "item_value_01": "Test",
                "quantity": 1
            },
            {
                "item_value_01": "Country",
                "quantity": 1
            }
        ],
        "month": "1",
        "year": "2023"
    }

Playbook

- set_fact:
        list: "{{ list|default({})| 
                    combine({item: input1[item]|default([]) +
                                   input2[item]|default([])}, recursive=true) }}"
     loop: "{{ (input2.keys()|list + input1.keys()|list)|unique }}"

Solution

  • Set list_merge='append' in the filter combine

      result: "{{ [input1, input2]|combine(list_merge='append') }}"
    

    gives the expected result

      result:
        data:
        - item_value_01: APPLICATION
          quantity: 1
        - item_value_01: HERBERT
          quantity: 1
        - item_value_01: Test
          quantity: 1
        - item_value_01: Country
          quantity: 1
        month: '1'
        year: '2023'
    

    Example of a complete playbook for testing

    - hosts: localhost
    
      vars:
    
        input1:
          data:
          - item_value_01: APPLICATION
            quantity: 1
          - item_value_01: HERBERT
            quantity: 1
          month: '1'
          year: '2023'
    
        input2:
          data:
          - item_value_01: Test
            quantity: 1
          - item_value_01: Country
            quantity: 1
          month: '1'
          year: '2023'
    
        result: "{{ [input1, input2]|combine(list_merge='append') }}"
    
      tasks:
    
        - debug:
            var: result