appending to nested dictionary

46 views
Skip to first unread message

darmar

unread,
Nov 30, 2023, 10:04:39 AM11/30/23
to Ansible Project
I am wondering how can i append the dictionary with subnet_id as key into vpc_result subnets element to look like below. Please find below all the tasks, vars and run output.


ok: [localhost] => {
    "vpc_result": [
        {
            "cidr_block": "10.10.8.0/21",
            "igw_id": "igw-0e06eba08c68ebf2b",
            "name": "A",
            "region": "eu-central-1",
            "subnets": {
                "10.10.8.0/24": {
                    "az": "a",
                    "map_public": true,
                    "subnet_id": "subnet-08b6790e6e51b6b78" <--
                },
                "10.10.9.0/24": {
                    "az": "b",
                    "subnet_id": "subnet-0e8512e1ace7ddc1f" <--
                }
            },
            "vpc_id": "vpc-000d7431c4a4f6e83"
        }
    ]
}

# roles/aws/defaults/main.yml

project: killerapp
customer: loser
stage: dev

resource_tags:
  Stage: "{{ stage }}"
  Application: "{{ project }}"
  Created-By: "Ansible for {{ customer }}"

vpc:
  - name: "A"
    cidr_block: "10.10.8.0/21"
    region: "eu-central-1"
    subnets:
      "10.10.8.0/24":
        az: "a"
        map_public: true
      "10.10.9.0/24":
        az: "b"
  - name: "B"
    cidr_block: "10.11.8.0/21"
    region: "eu-west-3"
    subnets:
      "10.11.8.0/24":
        az: "a"
        map_public: true
      "10.11.9.0/24":
        az: "b"

# roles/aws/tasks/main.yml
- name: Create VPC for each region
  loop: "{{ vpc }}"
  include_tasks: vpc.yml
  vars:
    region: "{{ item.region }}"
    name: "{{ item.name }}"
    cidr_block: "{{ item.cidr_block }}"
    subnets: "{{ item.subnets }}"

- name: "Report of generated networking"
  debug:
    var: vpc_result

# roles/aws/tasks/vpc.yml
- name: Create virtual private network for VPC {{ name }}
  ec2_vpc_net:
    region: "{{ region }}"
    name: "{{ name }}"
    cidr_block: "{{ cidr_block }}"
    tags: "{{ resource_tags }}"
  register: created_vpc

- name: Create internet gateway for VPC {{ name }} in {{ region }}
  ec2_vpc_igw:
    vpc_id: "{{ created_vpc.vpc.id }}"
    region: "{{ region }}"
    tags: "{{ resource_tags | combine({'Name': 'VPC internet gateway'}) }}"
  register: created_igw

- set_fact:
    vpc_result: "{{ vpc_result | default([]) + [{
      'name': created_vpc.vpc.name,
      'igw_id': created_igw.gateway_id,
      'vpc_id': created_vpc.vpc.id,
      'region': region,
      'subnets': subnets,
      'cidr_block': cidr_block
    }] }}"

- name: Create subnets in VPC {{ name }} in {{ region }}
  loop: "{{ subnets | list }}"
  loop_control:
    loop_var: subnet
  include_tasks: vpc_subnet.yml

# roles/aws/tasks/vpc_subnet.yml
- name: Create subnet {{ subnet }} for {{ name }} VPC in region {{ region }}
  ec2_vpc_subnet:
    vpc_id: "{{ created_vpc.vpc.id }}"
    region: "{{ region }}"
    cidr: "{{ subnet }}"
    tags: "{{ resource_tags | combine({'Name': subnet, 'Type': subnets[subnet].map_public|default(false) | ternary('public', 'private')}) }}"
    az: "{{ region }}{{ subnets[subnet].az }}"
    map_public: "{{ subnets[subnet].map_public | default(false) }}"
  register: created_subnet
  retries: 3
  delay: 5

- debug:
    var: created_subnet.subnet.id

# output
❯ ansible-playbook aws.yml

PLAY [localhost]
***********************************************************************************************************************************************************************************************************************************************************************************************************

TASK [roles/aws : Create VPC for each region]
******************************************************************************************************************************************************************************************************************************************************************************
included: /Users/tmihalicek/projects/ansible/bjesomar/roles/aws/tasks/vpc.yml for localhost => (item={'name': 'A', 'cidr_block': '10.10.8.0/21', 'region': 'eu-central-1', 'subnets': {'10.10.8.0/24': {'az': 'a', 'map_public': True}, '10.10.9.0/24': {'az': 'b'}}})
included: /Users/tmihalicek/projects/ansible/bjesomar/roles/aws/tasks/vpc.yml for localhost => (item={'name': 'B', 'cidr_block': '10.11.8.0/21', 'region': 'eu-west-3', 'subnets': {'10.11.8.0/24': {'az': 'a', 'map_public': True}, '10.11.9.0/24': {'az': 'b'}}})

TASK [roles/aws : Create virtual private network for VPC A]
****************************************************************************************************************************************************************************************************************************************************************
ok: [localhost]

TASK [roles/aws : Create internet gateway for VPC A in eu-central-1]
*******************************************************************************************************************************************************************************************************************************************************
ok: [localhost]

TASK [roles/aws : set_fact]
************************************************************************************************************************************************************************************************************************************************************************************************
ok: [localhost]

TASK [roles/aws : Create subnets in VPC A in eu-central-1]
*****************************************************************************************************************************************************************************************************************************************************************
included: /Users/tmihalicek/projects/ansible/bjesomar/roles/aws/tasks/vpc_subnet.yml for localhost => (item=10.10.8.0/24)
included: /Users/tmihalicek/projects/ansible/bjesomar/roles/aws/tasks/vpc_subnet.yml for localhost => (item=10.10.9.0/24)

TASK [roles/aws : Create subnet 10.10.8.0/24 for A VPC in region eu-central-1]
*********************************************************************************************************************************************************************************************************************************************
ok: [localhost]

TASK [roles/aws : debug]
***************************************************************************************************************************************************************************************************************************************************************************************************
ok: [localhost] => {
    "created_subnet.subnet.id": "subnet-0e8512e1ace7ddc1f"
}

TASK [roles/aws : Create subnet 10.10.9.0/24 for A VPC in region eu-central-1]
*********************************************************************************************************************************************************************************************************************************************
ok: [localhost]

TASK [roles/aws : debug]
***************************************************************************************************************************************************************************************************************************************************************************************************
ok: [localhost] => {
    "created_subnet.subnet.id": "subnet-08b6790e6e51b6b78"
}

TASK [roles/aws : Create virtual private network for VPC B]
****************************************************************************************************************************************************************************************************************************************************************
ok: [localhost]

TASK [roles/aws : Create internet gateway for VPC B in eu-west-3]
**********************************************************************************************************************************************************************************************************************************************************
ok: [localhost]

TASK [roles/aws : set_fact]
************************************************************************************************************************************************************************************************************************************************************************************************
ok: [localhost]

TASK [roles/aws : Create subnets in VPC B in eu-west-3]
********************************************************************************************************************************************************************************************************************************************************************
included: /Users/tmihalicek/projects/ansible/bjesomar/roles/aws/tasks/vpc_subnet.yml for localhost => (item=10.11.8.0/24)
included: /Users/tmihalicek/projects/ansible/bjesomar/roles/aws/tasks/vpc_subnet.yml for localhost => (item=10.11.9.0/24)

TASK [roles/aws : Create subnet 10.11.8.0/24 for B VPC in region eu-west-3]
************************************************************************************************************************************************************************************************************************************************
ok: [localhost]

TASK [roles/aws : debug]
***************************************************************************************************************************************************************************************************************************************************************************************************
ok: [localhost] => {
    "created_subnet.subnet.id": "subnet-06f30eb3f764c6f0c"
}

TASK [roles/aws : Create subnet 10.11.9.0/24 for B VPC in region eu-west-3]
************************************************************************************************************************************************************************************************************************************************
ok: [localhost]

TASK [roles/aws : debug]
***************************************************************************************************************************************************************************************************************************************************************************************************
ok: [localhost] => {
    "created_subnet.subnet.id": "subnet-01b797ba47beb350e"
}

TASK [roles/aws : Report of generated networking]
**************************************************************************************************************************************************************************************************************************************************************************
ok: [localhost] => {
    "vpc_result": [
        {
            "cidr_block": "10.10.8.0/21",
            "igw_id": "igw-0e06eba08c68ebf2b",
            "name": "A",
            "region": "eu-central-1",
            "subnets": {
                "10.10.8.0/24": {
                    "az": "a",
                    "map_public": true
                },
                "10.10.9.0/24": {
                    "az": "b"
                }
            },
            "vpc_id": "vpc-000d7431c4a4f6e83"
        },
        {
            "cidr_block": "10.11.8.0/21",
            "igw_id": "igw-0e11aad5926a77e02",
            "name": "B",
            "region": "eu-west-3",
            "subnets": {
                "10.11.8.0/24": {
                    "az": "a",
                    "map_public": true
                },
                "10.11.9.0/24": {
                    "az": "b"
                }
            },
            "vpc_id": "vpc-010721abf4a235e03"
        }
    ]
}

PLAY RECAP
*****************************************************************************************************************************************************************************************************************************************************************************************************************
localhost                  : ok=21   changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

Todd Lewis

unread,
Nov 30, 2023, 3:30:18 PM11/30/23
to ansible...@googlegroups.com, uto...@gmail.com
This is untested, but you would end up doing effectively the same as this:
set_fact:
  vpc_result: '{{ [vpc_result[0] | combine({"subnets":
                                             {"10.10.8.0/24":
                                               {"subnet_id": "subnet-08b6790e6e51b6b78"}
                                             },
                                             {"10.10.9.0/24":
                                               {"subnet_id": "subnet-0e8512e1ace7ddc1f"}
                                             }
                                            })] }}'
Here's a link to the ansible.builtin.combine filter docs. Note that combine works on dictionaries, and vpc_result is a single element list. That's why the whole expression is enclosed in [] and we combine on vpc_result[0] instead of vpc_result.
--
You received this message because you are subscribed to the Google Groups "Ansible Project" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ansible-proje...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/ansible-project/faa1d4bc-ed7b-43b0-bd9d-60beafb6595en%40googlegroups.com.

-- 
Todd
Reply all
Reply to author
Forward
0 new messages