Home > Software design >  Ansible combine list of items in single list
Ansible combine list of items in single list

Time:12-06

There is probably simple solution to this i just cant figure it out. I got the following list in Ansible:

result: [
  {
    "name": "DC1",
    "net": "10.10.1.0"
  },
  {
    "name": "DC1",
    "net": "10.10.2.0"
  },
  {
    "name": "DC2",
    "net": "10.10.3.0"
  },
]

and would like to get the new list in this format:

[
 {
    "name": "DC1",
    "net": ["10.10.1.0","10.10.2.0"]
  },
 {
    "name": "DC2",
    "net": "10.10.3.0"
  }
]

CodePudding user response:

There are more options.

  1. The simplest option is converting the addresses to the lists
  net_lists: "{{ result|json_query('[].{name: name, net: [net]}') }}"

gives

  net_lists:
    - name: DC1
      net: [10.10.1.0]
    - name: DC1
      net: [10.10.2.0]
    - name: DC2
      net: [10.10.3.0]

Then, merge the items by name and append the lists

  net_list: "{{ [net_lists, []]|
                community.general.lists_mergeby('name', list_merge='append') }}"

gives what you want

  net_list:
    - name: DC1
      net: [10.10.1.0, 10.10.2.0]
    - name: DC2
      net: [10.10.3.0]

Example of a complete playbook for testing

- hosts: localhost

  vars:

    result:
      - name: DC1
        net: 10.10.1.0
      - name: DC1
        net: 10.10.2.0
      - name: DC2
        net: 10.10.3.0

    net_lists: "{{ result|json_query('[].{name: name, net: [net]}') }}"
    net_list: "{{ [net_lists, []]|
                  community.general.lists_mergeby('name', list_merge='append') }}"

  tasks:

    - debug:
        var: net_lists|to_yaml
    - debug:
        var: net_list|to_yaml

  1. The next option is grouping the items by name, selecting the keys and values, and creating a dictionary. Declare the variables
  net_groups: "{{ result|groupby('name') }}"
  net_names: "{{ net_groups|map('first')|list }}"
  net_lists: "{{ net_groups|map('last')|
                            map('map', attribute='net')|list }}"
  net_dict: "{{ dict(net_names|zip(net_lists)) }}"
  net_list: "{{ net_dict|dict2items(key_name='name', value_name='net') }}"

give

  net_groups:
    - - DC1
      - - {name: DC1, net: 10.10.1.0}
        - {name: DC1, net: 10.10.2.0}
    - - DC2
      - - {name: DC2, net: 10.10.3.0}
  net_names: [DC1, DC2]
  net_lists:
    - [10.10.1.0, 10.10.2.0]
    - [10.10.3.0]
  net_dict:
    DC1: [10.10.1.0, 10.10.2.0]
    DC2: [10.10.3.0]
  net_list:
    - name: DC1
      net: [10.10.1.0, 10.10.2.0]
    - name: DC2
      net: [10.10.3.0]

Example of a complete playbook for testing

- hosts: localhost

  vars:

    result:
      - name: DC1
        net: 10.10.1.0
      - name: DC1
        net: 10.10.2.0
      - name: DC2
        net: 10.10.3.0

    net_groups: "{{ result|groupby('name') }}"
    net_names: "{{ net_groups|map('first')|list }}"
    net_lists: "{{ net_groups|map('last')|
                              map('map', attribute='net')|list }}"
    net_dict: "{{ dict(net_names|zip(net_lists)) }}"
    net_list: "{{ net_dict|dict2items(key_name='name', value_name='net') }}"

  tasks:

    - debug:
        var: net_groups|to_yaml
    - debug:
        var: net_names|to_yaml
    - debug:
        var: net_lists|to_yaml
    - debug:
        var: net_dict|to_yaml
    - debug:
        var: net_list|to_yaml

  • Related