Q: Ansible - How can I merge 2 lists of hashes wit

2019-07-25 10:12发布

问题:

How can I merge 2 lists of hashes based on a key/value pair, using Ansible 2.4.4

"foo": [
    {
        "hostname": "web1.example.com",
        "guid": "73e85eb2-2ad5-4699-8a09-adf658a11ff2"
    },
    {
        "hostname": "web2.example.com",
        "guid": "827025fe-f13c-4fc8-ba51-7ff582596bbd"
    },
    {
        "hostname": "web3.example.com",
        "guid": "bba27304-c1bb-4889-aa44-125626be8488"
    }
]

"bar": [
    {
        "ipaddress": "1.1.1.1",
        "guid": "73e85eb2-2ad5-4699-8a09-adf658a11ff2"
    },
    {
        "ipaddress": "2.2.2.2",
        "guid": "827025fe-f13c-4fc8-ba51-7ff582596bbd"
    },
    {
        "ipaddress": "3.3.3.3",
        "guid": "bba27304-c1bb-4889-aa44-125626be8488"
    }
]

I want something like:

"foobar" : [
    {
        "hostname": "web1.example.com",
        "guid": "73e85eb2-2ad5-4699-8a09-adf658a11ff2",
        "ipaddress": "1.1.1.1"
    },
    {
        "hostname": "web2.example.com",
        "guid": "827025fe-f13c-4fc8-ba51-7ff582596bbd",
        "ipaddress": "2.2.2.2"
    },
    {
        "hostname": "web3.example.com",
        "guid": "bba27304-c1bb-4889-aa44-125626be8488",
        "ipaddress": "3.3.3.3"
    }
]

I've looked into several Ansible / Jinja2 filters including combine, union, map, custom plugins, but not having much success. I need to be able to match on the guid.

回答1:

not sure if there is a smarter way, but to achieve what you need you can use the nested query plugin to loop over the combinations of the elements from the 2 list variables, find the combinations that have the common field equal, and then construct a new dictionary element and append it to the "final" list variable.

playbook:

- hosts: localhost
  gather_facts: false
  vars:
    foo:
      - hostname: web1.example.com
        guid: 73e85eb2-2ad5-4699-8a09-adf658a11ff2
      - hostname: web2.example.com
        guid: 827025fe-f13c-4fc8-ba51-7ff582596bbd
      - hostname: web3.example.com
        guid: bba27304-c1bb-4889-aa44-125626be8488
    bar:
      - ipaddress: 1.1.1.1
        guid: 73e85eb2-2ad5-4699-8a09-adf658a11ff2
      - ipaddress: 2.2.2.2
        guid: 827025fe-f13c-4fc8-ba51-7ff582596bbd
      - ipaddress: 3.3.3.3
        guid: bba27304-c1bb-4889-aa44-125626be8488

  tasks:

    - name: merge lists
      set_fact:
        merged_list: "{{ merged_list|default([]) + [{ 'hostname': item[0].hostname, 'guid': item[0].guid, 'ipaddress': item[1].ipaddress }] }}"
      when: "item[0].guid == item[1].guid"
      loop: "{{ query('nested', foo, bar) }}"

    - name: print results
      debug:
        var: merged_list

result:

TASK [print results] ************************************************************************************************************************************************************************************************
ok: [localhost] => {
    "merged_list": [
        {
            "guid": "73e85eb2-2ad5-4699-8a09-adf658a11ff2", 
            "hostname": "web1.example.com", 
            "ipaddress": "1.1.1.1"
        }, 
        {
            "guid": "827025fe-f13c-4fc8-ba51-7ff582596bbd", 
            "hostname": "web2.example.com", 
            "ipaddress": "2.2.2.2"
        }, 
        {
            "guid": "bba27304-c1bb-4889-aa44-125626be8488", 
            "hostname": "web3.example.com", 
            "ipaddress": "3.3.3.3"
        }
    ]
}


标签: ansible