'ansible modify a delete value in nested dictonary

I would like to add new value in nested dictionary and old value should be delete.

Here is my parse.json file.

{
    "class": "Service_HTTPS",
    "layer4": "tcp",
    "profileTCP": {
        "egress": {
            "use": "/Common/Shared/f5-tcp-wan"
        },
        "ingress": {
            "use": "/Common/Shared/f5-tcp-lan"
        }
    }
}

This is my script which will add new value but also is keep old value,I know I am using recursive=True but without this command I am loss ingress key. Here is my script

- set_fact:
        json_file: "{{ lookup('file', 'parse.json')   }}"
    

    - set_fact:
        json_file: "{{ json_file | combine( egress_modify, recursive=True) }}"
      when: json_file['profileTCP']['egress'] is defined
      vars: 
        egress_modify: "{{ json_file  | combine({ 'profileTCP': { 'egress': { 'bigip': '/Common/' + json_file['profileTCP']['egress']['use'].split('/')[-1] } }}) }}" 
        

    - name: debug
      debug:
          msg: "{{ json_file }}"

wrong result

ok: [localhost] => {
    "msg": {
        "class": "Service_HTTPS",
        "layer4": "tcp",
        "profileTCP": {
            "egress": {
                "bigip": "/Common/f5-tcp-wan",
                "use": "/Common/Shared/f5-tcp-wan"
            },
            "ingress": {
                "use": "/Common/Shared/f5-tcp-lan"
            }
        }
    }
}

but I would like to have this result

ok: [localhost] => {
    "msg": {
        "class": "Service_HTTPS",
        "layer4": "tcp",
        "profileTCP": {
            "egress": {
                "bigip": "/Common/f5-tcp-wan",
            },
            "ingress": {
                "use": "/Common/Shared/f5-tcp-lan"
            }
        }
    }
}




Solution 1:[1]

dicts are "live" in ansible, so you can either continue to do that "set_fact:, loop:" business, or you can do it all in one shot:

    - set_fact:
        json_file: >-
          {%- set j = lookup('file', 'parse.json') | from_json -%}
          {%- set tcp_egress_use = j.profileTCP.egress.pop('use') -%}
          {%- set _ = j.profileTCP.egress.update({
                'bigip': '/Common/' + tcp_egress_use.split('/')[-1]
              }) -%}
          {{ j }}

produces

    "json_file": {
      "class": "Service_HTTPS",
      "layer4": "tcp",
      "profileTCP": {
        "egress": {
          "bigip": "/Common/f5-tcp-wan"
        },
        "ingress": {
          "use": "/Common/Shared/f5-tcp-lan"
        }
      }
    }

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 mdaniel