aws-cloudformation/centralized_architecture/CentralizedArchitectureApplianceVpc2Az.yaml [902:1101]:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      Handler: "index.handler"
      Role: !GetAtt VpceServiceLambdaExecutionRole.Arn
      Code:
        ZipFile: |
          import json
          import logging
          import time

          import boto3
          import cfnresponse
          from botocore.exceptions import ClientError

          try:
              ec2 = boto3.client('ec2')
          except ClientError as e:
              logger.error(f"ERROR: failed to connect to EC2 client: {e}")
              sys.exit(1)              

          def handler(event, context):
              logger = logging.getLogger()
              logger.setLevel(logging.INFO)
              logger.info('Received event: {}'.format(json.dumps(event)))

              responseData = {}
              responseStatus = cfnresponse.FAILED

              try:
                  serviceid = event["ResourceProperties"]["VpceServiceId"]                
              except Exception as e:
                  logger.info('Attribute retrival failure: {}'.format(e))

              try:
                  if event["RequestType"] == "Delete":    
                      responseStatus = cfnresponse.SUCCESS
                      cfnresponse.send(event, context, responseStatus, responseData)
              except Exception:
                  logger.exception("Signaling failure to CloudFormation.")
                  cfnresponse.send(event, context, cfnresponse.FAILED, {})

              if event["RequestType"] == "Create":
                  logger.info("Retrieving VPC Endpoint Service Name:")
                  try:
                      response = ec2.describe_vpc_endpoint_service_configurations(
                          Filters=[
                              {
                                  'Name': 'service-id',
                                  'Values': [serviceid]
                              }
                          ]
                      )
                  except Exception as e:
                      logger.info('ec2.describe_vpc_endpoint_service_configurations failure: {}'.format(e))

                  service_name = response['ServiceConfigurations'][0]['ServiceName']

                  time.sleep(120)

                  responseData['ServiceName'] = service_name             
                  responseStatus = cfnresponse.SUCCESS
                  cfnresponse.send(event, context, responseStatus, responseData)
      Runtime: python3.7
      Timeout: 150

  RetrieveVpceServiceName:
    Type: Custom::RetrieveAttributes
    Properties:
      ServiceToken: !GetAtt VpceServiceName.Arn
      VpceServiceId: !Ref VpcEndpointService

# Create Gateway Load Balancer Endpoint:

  GwlbEndpoint1:
    Type: AWS::EC2::VPCEndpoint
    Properties:
      VpcId: !Ref Vpc
      ServiceName: !GetAtt RetrieveVpceServiceName.ServiceName
      VpcEndpointType: GatewayLoadBalancer
      SubnetIds:
        - !Ref ApplianceSubnet1

  GwlbEndpoint2:
    Type: AWS::EC2::VPCEndpoint
    Properties:
      VpcId: !Ref Vpc
      ServiceName: !GetAtt RetrieveVpceServiceName.ServiceName
      VpcEndpointType: GatewayLoadBalancer
      SubnetIds:
        - !Ref ApplianceSubnet2

# Create appropriate routes for appropriate route tables. Routes with TGW as target are added through TGW template.
  # AZ1:
  NatgwRtb1IgwRoute:
    Type: AWS::EC2::Route
    DependsOn: AttachInternetGateway
    Properties:
      DestinationCidrBlock: !Ref AccessLocation
      GatewayId: !Ref InternetGateway
      RouteTableId: !Ref NatGwRouteTable1

  NatgwRtb1Gwlbe1Route:
    Type: AWS::EC2::Route
    DependsOn: GwlbEndpoint1
    Properties:
      DestinationCidrBlock: !Ref Spoke1VpcCidr
      VpcEndpointId: !Ref GwlbEndpoint1
      RouteTableId: !Ref NatGwRouteTable1

  NatgwRtb1Gwlbe2Route:
    Type: AWS::EC2::Route
    DependsOn: GwlbEndpoint2
    Properties:
      DestinationCidrBlock: !Ref Spoke2VpcCidr
      VpcEndpointId: !Ref GwlbEndpoint1
      RouteTableId: !Ref NatGwRouteTable1

  ApplianceRtb1Natgw1Route:
    Type: AWS::EC2::Route
    DependsOn: Natgw1
    Properties:
      DestinationCidrBlock: !Ref AccessLocation
      NatGatewayId: !Ref Natgw1
      RouteTableId: !Ref ApplianceRouteTable1
  
  TgwAttachRtb1Gwlbe1Route:
    Type: AWS::EC2::Route
    DependsOn: GwlbEndpoint1
    Properties:
      DestinationCidrBlock: !Ref AccessLocation
      VpcEndpointId: !Ref GwlbEndpoint1
      RouteTableId: !Ref TgwAttachRouteTable1

  # AZ2:
  NatgwRtb2IgwRoute:
    Type: AWS::EC2::Route
    DependsOn: AttachInternetGateway
    Properties:
      DestinationCidrBlock: !Ref AccessLocation
      GatewayId: !Ref InternetGateway
      RouteTableId: !Ref NatGwRouteTable2

  NatgwRtb2Gwlbe1Route:
    Type: AWS::EC2::Route
    DependsOn: GwlbEndpoint1
    Properties:
      DestinationCidrBlock: !Ref Spoke1VpcCidr
      VpcEndpointId: !Ref GwlbEndpoint2
      RouteTableId: !Ref NatGwRouteTable2

  NatgwRtb2Gwlbe2Route:
    Type: AWS::EC2::Route
    DependsOn: GwlbEndpoint2
    Properties:
      DestinationCidrBlock: !Ref Spoke2VpcCidr
      VpcEndpointId: !Ref GwlbEndpoint2
      RouteTableId: !Ref NatGwRouteTable2

  ApplianceRtb2Natgw2Route:
    Type: AWS::EC2::Route
    DependsOn: Natgw2
    Properties:
      DestinationCidrBlock: !Ref AccessLocation
      NatGatewayId: !Ref Natgw2
      RouteTableId: !Ref ApplianceRouteTable2
  
  TgwAttachRtb2Gwlbe2Route:
    Type: AWS::EC2::Route
    DependsOn: GwlbEndpoint2
    Properties:
      DestinationCidrBlock: !Ref AccessLocation
      VpcEndpointId: !Ref GwlbEndpoint2
      RouteTableId: !Ref TgwAttachRouteTable2

Outputs:
  ApplianceVpcCidr:
    Description: Appliance VPC CIDR
    Value: !Ref VpcCidr
  ApplianceVpcId:
    Description: Appliance VPC ID
    Value: !Ref Vpc
  Appliance1PrivateIp:
    Description: Appliance VPC Appliance1's private IP
    Value: !GetAtt Appliance1.PrivateIp
  Appliance2PrivateIp:
    Description: Appliance VPC Appliance2's private IP
    Value: !GetAtt Appliance2.PrivateIp
  ApplianceBastionHostPublicIp:
    Description: Appliance VPC Bastion Instance Public IP
    Value: !GetAtt BastionHost.PublicIp
  ApplianceTgwAttachSubnet1Id:
    Description: Appliance VPC TgwAttachSubnet1 ID
    Value: !Ref TgwAttachSubnet1
  ApplianceTgwAttachSubnet2Id:
    Description: Appliance VPC TgwAttachSubnet2 ID
    Value: !Ref TgwAttachSubnet2       
  ApplianceRtb1Id:
    Description: Appliance VPC gwlb-rtb1's id
    Value: !Ref ApplianceRouteTable1
  ApplianceRtb2Id:
    Description: Appliance VPC gwlb-rtb2's id
    Value: !Ref ApplianceRouteTable2
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -



aws-cloudformation/centralized_architecture/nested-stack/ApplianceVpc2Az.yaml [901:1100]:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      Handler: "index.handler"
      Role: !GetAtt VpceServiceLambdaExecutionRole.Arn
      Code:
        ZipFile: |
          import json
          import logging
          import time

          import boto3
          import cfnresponse
          from botocore.exceptions import ClientError

          try:
              ec2 = boto3.client('ec2')
          except ClientError as e:
              logger.error(f"ERROR: failed to connect to EC2 client: {e}")
              sys.exit(1)              

          def handler(event, context):
              logger = logging.getLogger()
              logger.setLevel(logging.INFO)
              logger.info('Received event: {}'.format(json.dumps(event)))

              responseData = {}
              responseStatus = cfnresponse.FAILED

              try:
                  serviceid = event["ResourceProperties"]["VpceServiceId"]                
              except Exception as e:
                  logger.info('Attribute retrival failure: {}'.format(e))

              try:
                  if event["RequestType"] == "Delete":    
                      responseStatus = cfnresponse.SUCCESS
                      cfnresponse.send(event, context, responseStatus, responseData)
              except Exception:
                  logger.exception("Signaling failure to CloudFormation.")
                  cfnresponse.send(event, context, cfnresponse.FAILED, {})

              if event["RequestType"] == "Create":
                  logger.info("Retrieving VPC Endpoint Service Name:")
                  try:
                      response = ec2.describe_vpc_endpoint_service_configurations(
                          Filters=[
                              {
                                  'Name': 'service-id',
                                  'Values': [serviceid]
                              }
                          ]
                      )
                  except Exception as e:
                      logger.info('ec2.describe_vpc_endpoint_service_configurations failure: {}'.format(e))

                  service_name = response['ServiceConfigurations'][0]['ServiceName']

                  time.sleep(120)

                  responseData['ServiceName'] = service_name             
                  responseStatus = cfnresponse.SUCCESS
                  cfnresponse.send(event, context, responseStatus, responseData)
      Runtime: python3.7
      Timeout: 150

  RetrieveVpceServiceName:
    Type: Custom::RetrieveAttributes
    Properties:
      ServiceToken: !GetAtt VpceServiceName.Arn
      VpceServiceId: !Ref VpcEndpointService

# Create Gateway Load Balancer Endpoint:

  GwlbEndpoint1:
    Type: AWS::EC2::VPCEndpoint
    Properties:
      VpcId: !Ref Vpc
      ServiceName: !GetAtt RetrieveVpceServiceName.ServiceName
      VpcEndpointType: GatewayLoadBalancer
      SubnetIds:
        - !Ref ApplianceSubnet1

  GwlbEndpoint2:
    Type: AWS::EC2::VPCEndpoint
    Properties:
      VpcId: !Ref Vpc
      ServiceName: !GetAtt RetrieveVpceServiceName.ServiceName
      VpcEndpointType: GatewayLoadBalancer
      SubnetIds:
        - !Ref ApplianceSubnet2

# Create appropriate routes for appropriate route tables. Routes with TGW as target are added through TGW template.
  # AZ1:
  NatgwRtb1IgwRoute:
    Type: AWS::EC2::Route
    DependsOn: AttachInternetGateway
    Properties:
      DestinationCidrBlock: !Ref AccessLocation
      GatewayId: !Ref InternetGateway
      RouteTableId: !Ref NatGwRouteTable1

  NatgwRtb1Gwlbe1Route:
    Type: AWS::EC2::Route
    DependsOn: GwlbEndpoint1
    Properties:
      DestinationCidrBlock: !Ref Spoke1VpcCidr
      VpcEndpointId: !Ref GwlbEndpoint1
      RouteTableId: !Ref NatGwRouteTable1

  NatgwRtb1Gwlbe2Route:
    Type: AWS::EC2::Route
    DependsOn: GwlbEndpoint2
    Properties:
      DestinationCidrBlock: !Ref Spoke2VpcCidr
      VpcEndpointId: !Ref GwlbEndpoint1
      RouteTableId: !Ref NatGwRouteTable1

  ApplianceRtb1Natgw1Route:
    Type: AWS::EC2::Route
    DependsOn: Natgw1
    Properties:
      DestinationCidrBlock: !Ref AccessLocation
      NatGatewayId: !Ref Natgw1
      RouteTableId: !Ref ApplianceRouteTable1
  
  TgwAttachRtb1Gwlbe1Route:
    Type: AWS::EC2::Route
    DependsOn: GwlbEndpoint1
    Properties:
      DestinationCidrBlock: !Ref AccessLocation
      VpcEndpointId: !Ref GwlbEndpoint1
      RouteTableId: !Ref TgwAttachRouteTable1

  # AZ2:
  NatgwRtb2IgwRoute:
    Type: AWS::EC2::Route
    DependsOn: AttachInternetGateway
    Properties:
      DestinationCidrBlock: !Ref AccessLocation
      GatewayId: !Ref InternetGateway
      RouteTableId: !Ref NatGwRouteTable2

  NatgwRtb2Gwlbe1Route:
    Type: AWS::EC2::Route
    DependsOn: GwlbEndpoint1
    Properties:
      DestinationCidrBlock: !Ref Spoke1VpcCidr
      VpcEndpointId: !Ref GwlbEndpoint2
      RouteTableId: !Ref NatGwRouteTable2

  NatgwRtb2Gwlbe2Route:
    Type: AWS::EC2::Route
    DependsOn: GwlbEndpoint2
    Properties:
      DestinationCidrBlock: !Ref Spoke2VpcCidr
      VpcEndpointId: !Ref GwlbEndpoint2
      RouteTableId: !Ref NatGwRouteTable2

  ApplianceRtb2Natgw2Route:
    Type: AWS::EC2::Route
    DependsOn: Natgw2
    Properties:
      DestinationCidrBlock: !Ref AccessLocation
      NatGatewayId: !Ref Natgw2
      RouteTableId: !Ref ApplianceRouteTable2
  
  TgwAttachRtb2Gwlbe2Route:
    Type: AWS::EC2::Route
    DependsOn: GwlbEndpoint2
    Properties:
      DestinationCidrBlock: !Ref AccessLocation
      VpcEndpointId: !Ref GwlbEndpoint2
      RouteTableId: !Ref TgwAttachRouteTable2

Outputs:
  ApplianceVpcCidr:
    Description: Appliance VPC CIDR
    Value: !Ref VpcCidr
  ApplianceVpcId:
    Description: Appliance VPC ID
    Value: !Ref Vpc
  Appliance1PrivateIp:
    Description: Appliance VPC Appliance1's private IP
    Value: !GetAtt Appliance1.PrivateIp
  Appliance2PrivateIp:
    Description: Appliance VPC Appliance2's private IP
    Value: !GetAtt Appliance2.PrivateIp
  ApplianceBastionHostPublicIp:
    Description: Appliance VPC Bastion Instance Public IP
    Value: !GetAtt BastionHost.PublicIp
  ApplianceTgwAttachSubnet1Id:
    Description: Appliance VPC TgwAttachSubnet1 ID
    Value: !Ref TgwAttachSubnet1
  ApplianceTgwAttachSubnet2Id:
    Description: Appliance VPC TgwAttachSubnet2 ID
    Value: !Ref TgwAttachSubnet2       
  ApplianceRtb1Id:
    Description: Appliance VPC gwlb-rtb1's id
    Value: !Ref ApplianceRouteTable1
  ApplianceRtb2Id:
    Description: Appliance VPC gwlb-rtb2's id
    Value: !Ref ApplianceRouteTable2
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -



