Search code examples
jsonansibleyamljinja2

combine 2 nested dictionaries


I am trying to add an additional entry to a nested dictionary. I am able to extract the nested dictionary, append to the dictionary but can't fully figure out how to replace the nested section with the newly created one. I have a feeling there is a much easier way to do this. I will just ask what I want in the end instead of posting what I have tried and see where it goes.

I need to add an additional entry under my_team that will come in as a var:

ok: [localhost] => changed=false 
  json:
    OTHER_KEYS_1: value1
    OTHER_KEYS_2:
      value1
      key1: value1
    OTHER_KEYS_3:
      key1: value1
      key2: value2
      my_team:
      - org: Default
        team: TEAM-ONE-ADMINS
      - org: Default
        team: TEAM-ONE-USERS
      - org: Default
        team: TEAM-TWO-USERS
      - org: Default
        team: TEAM-TWO-ADMINS
      - org: Default
        team: TEAM-THREE-USERS
      - org: Default
        team: TEAM-THREE-ADMINS
    OTHER_KEYS_4: {}
    OTHER_KEYS_5:
      emailAddress: [email protected]
      givenName: User Name
    OTHER_KEYS_6:
      key1: value1
  msg: OK (7003 bytes)
  pragma: no-cache
  redirected: false
  server: nginx
  status: 200
  strict_transport_security: max-age=63072000
  url: https://tower/api/v2/settings/saml/?format=json
  vary: Accept, Accept-Language, Origin, Cookie

Solution

  • Q: "Add an additional entry under my_team."

    A: Given simplified data

        data:
          k1: v1
          k2: v2
          k3:
            key1: value1
            key2: value2
            my_team:
              - {org: default, team: team_one}
              - {org: default, team: team_two}
    

    Declare what you want to add

        data_add:
          k3:
            my_team:
              - {org: default, team: team_three}
    

    and combine the dictionaries

      result: "{{ [data, data_add]|combine(recursive=True, list_merge='append') }}"
    

    gives the dictionary with an additional entry under my_team

      result:
        k1: v1
        k2: v2
        k3:
          key1: value1
          key2: value2
          my_team:
          - {org: default, team: team_one}
          - {org: default, team: team_two}
          - {org: default, team: team_three}
    

    Example of a complete playbook for testing

    - hosts: all
    
      vars:
    
        data:
          k1: v1
          k2: v2
          k3:
            key1: value1
            key2: value2
            my_team:
              - {org: default, team: team_one}
              - {org: default, team: team_two}
    
        data_add:
          k3:
            my_team:
              - {org: default, team: team_three}
    
        result: "{{ [data, data_add]|combine(recursive=True, list_merge='append') }}"
    
      tasks:
    
        - debug:
            var: data|to_yaml
    
        - debug:
            var: result|to_yaml