Two non identical dictionaries

Viewed 65

I am newbie in Ansible and I have 2 dictionaries:

dict1: { "env1":{"s": "1002a", "t": "1002b"},"env2": { "s": "1002a", "t": "1002b" }
dict2: {"1002b-aa": "abcde"}

I want to change the value or create a new dictionary which looks like

new_dict: { "env1":{"s": "1002a", "t": "abcde"},"env2": { "s": "1002a", "t": "abcde" }

Note that in dict1 value t (1002b) partially matches with dict2 key (1002b-aa)

Thanks in advance.

1 Answers

The playbook below does the job

shell> cat pb.yml
- hosts: localhost

  vars:

    dict1: {}
    dict2: {}
    new_dict: "{{ dict1 }}"

  tasks:
  
    - set_fact:
        new_dict: "{{ new_dict|combine(env|from_yaml, recursive=True) }}"
      with_nested:
        - "{{ dict1|dict2items }}"
        - "{{ dict2|dict2items }}"
      vars:
        env: >-
          {{ item.0.key }}: {
          {%- for k,v in item.0.value.items() %}
          {%- if item.1.key is search(v) %}
          {{ k }}: {{ item.1.value }},
          {%- endif %}
          {%- endfor %}
          }

    - debug:
        var: new_dict
  1. gives (abridged) matching attribute 't'
shell> cat test-data-01.yml 
dict1: {"env1": {"s": "1002a", "t": "1002b"},
        "env2": {"s": "1002a", "t": "1002b"}}
dict2: {"1002b-aa": "abcde"}
shell> ansible-playbook pb.yml -e @test-data-01.yml
...
  new_dict:
    env1:
      s: 1002a
      t: abcde
    env2:
      s: 1002a
      t: abcde
  1. gives (abridged) matching both attributes 's' and 't'
shell> cat test-data-02.yml 
dict1: {"env1": {"s": "1002a", "t": "1002b"},
        "env2": {"s": "1002a", "t": "1002b"}}
dict2: {"1002b-aa": "abcde", "1002a-aa": "efgh"}
shell> ansible-playbook pb.yml -e @test-data-02.yml
...
  new_dict:
    env1:
      s: efgh
      t: abcde
    env2:
      s: efgh
      t: abcde
  1. gives (abridged) no match
shell> cat test-data-03.yml 
dict1: {"env1": {"s": "1002a", "t": "1002b"},
        "env2": {"s": "1002a", "t": "1002b"}}
dict2: {"999": "abcde"}
shell> ansible-playbook pb.yml -e @test-data-03.yml
...
  new_dict:
    env1:
      s: 1002a
      t: 1002b
    env2:
      s: 1002a
      t: 1002b
  1. gives (abridged) if there are more matches the last one wins
shell> cat test-data-04.yml 
dict1: {"env1": {"s": "1002a", "t": "1002b"},
        "env2": {"s": "1002a", "t": "1002b"}}
dict2: {"1002b-aa": "abcde", "1002b-bb": "efgh"}
shell> ansible-playbook pb.yml -e @test-data-04.yml
...
  new_dict:
    env1:
      s: 1002a
      t: efgh
    env2:
      s: 1002a
      t: efgh
  1. gives (abridged) more matches in a single iteration
shell> cat test-data-05.yml 
dict1: {"env1": {"s": "1002", "t": "1002"},
        "env2": {"s": "1003", "t": "1004"}}
dict2: {"1002b-aa": "abc", "1002b-bb": "def", "1003c-cc": "ghi", "1004d-dd": "jkl"}
shell> ansible-playbook pb.yml -e @test-data-05.yml
...
  new_dict:
    env1:
      s: def
      t: def
    env2:
      s: ghi
      t: jkl
Related