The source nested dictionary is for instance the following:
vpc:
provider:
- net_type: ‘db’
net_ipv4_subnet: ‘10.0.0.0/16’
net_ipv6_subnet: ‘FD00::/64’
net_id: 0
nic_ids: - 1111111111
- 2222222222
- net_type: ‘dns’
net_ipv4_subnet: ‘10.1.0.0/16’
net_ipv6_subnet: ‘FD01::/64’
net_id: 1
nic_ids: - 3333333333
- 4444444444
- net_type: ‘ns’
net_ipv4_subnet: ‘10.2.0.0/16’
net_ipv6_subnet: ‘FD02::/64’
net_id: 2
nic_ids: - 5555555555
- 6666666666
We need to replace only the whole entry indexed by “net_type: ‘dns’” with:
- net_type: ‘dns’
net_ipv4_subnet: ‘10.3.0.0/16’
net_ipv6_subnet: ‘FD03::/64’
net_id: 3
nic_ids:
so the result would look like:
vpc:
provider:
- net_type: ‘db’
net_ipv4_subnet: ‘10.0.0.0/16’
net_ipv6_subnet: ‘FD00::/64’
net_id: 0
nic_ids: - 1111111111
- 2222222222
- net_type: ‘dns’
net_ipv4_subnet: ‘10.3.0.0/16’
net_ipv6_subnet: ‘FD03::/64’
net_id: 3
nic_ids: - net_type: ‘ns’
net_ipv4_subnet: ‘10.2.0.0/16’
net_ipv6_subnet: ‘FD02::/64’
net_id: 2
nic_ids: - 5555555555
- 6666666666
I’ve tried the following task using the combine filter:
- name: Combining 2 dictionaries with combine/list_merge=‘replace’
vars:
vpc:
provider: - net_type: ‘db’
net_ipv4_subnet: ‘10.0.0.0/16’
net_ipv6_subnet: ‘FD00::/64’
net_id: 0
nic_ids: - 1111111111
- 2222222222
- net_type: ‘dns’
net_ipv4_subnet: ‘10.1.0.0/16’
net_ipv6_subnet: ‘FD01::/64’
net_id: 1
nic_ids: - 3333333333
- 4444444444
- net_type: ‘ns’
net_ipv4_subnet: ‘10.2.0.0/16’
net_ipv6_subnet: ‘FD02::/64’
net_id: 2
nic_ids: - 5555555555
- 6666666666
net_id: 3
net_ipv4_subnet: ‘10.3.0.0/16’
net_ipv6_subnet: ‘FD03::/64’
new_vpc: “{{ vpc | combine({‘provider’: [{‘net_type’: ‘dns’, ‘net_id’: net_id, ‘net_ipv4_subnet’: net_ipv4_subnet, ‘net_ipv6_subnet’: net_ipv6_subnet, ‘nic_ids’: }]}, recursive=True, list_merge=‘replace’) }}”
debug:
msg: “{{ new_vpc }}”
which unfortunately removes the other 2 entries:
ok: [localhost] =>
msg:
provider:
- net_id: 3
net_ipv4_subnet: 10.3.0.0/16
net_ipv6_subnet: FD03::/64
net_type: dns
nic_ids:
Same result with community.general.lists_mergeby filter:
- name: Combining 2 dictionaries with lists_mergeby/list_merge=‘replace’
vars:
vpc:
provider: - net_type: ‘db’
net_ipv4_subnet: ‘10.0.0.0/16’
net_ipv6_subnet: ‘FD00::/64’
net_id: 0
nic_ids: - 1111111111
- 2222222222
- net_type: ‘dns’
net_ipv4_subnet: ‘10.1.0.0/16’
net_ipv6_subnet: ‘FD01::/64’
net_id: 1
nic_ids: - 3333333333
- 4444444444
- net_type: ‘ns’
net_ipv4_subnet: ‘10.2.0.0/16’
net_ipv6_subnet: ‘FD02::/64’
net_id: 2
nic_ids: - 5555555555
- 6666666666
seed_vpc:
provider: - net_type: ‘dns’
net_ipv4_subnet: ‘10.3.0.0/16’
net_ipv6_subnet: ‘FD03::/64’
net_id: 3
nic_ids:
new_vpc: “{{ [vpc.provider, seed_vpc.provider] | community.general.lists_mergeby(‘net_type=dns’, recursive=True, list_merge=‘replace’) }}”
debug:
msg: “{{ new_vpc }}”
leads to:
ok: [localhost] =>
msg:
provider:
- net_id: 3
net_ipv4_subnet: 10.3.0.0/16
net_ipv6_subnet: FD03::/64
net_type: dns
nic_ids:
Am I missing something or is it impossible to perform with the currently available ansible filters?