AWSTemplateFormatVersion: '2010-09-09' Description: A VPC with two private subnets, two public subnets with NAT gateway, and an internet gateway. Network routing for the public subnets will be configured to allow outbound access directly via an Internet Gateway. Network routing for the private subnets will be configured to allow outbound access via a set of NAT Gateways. Mappings: # The VPC and subnet configuration is passed in via the environment spec. SubnetConfig: VPC: CIDR: '10.0.0.0/16' Public1: CIDR: '10.0.0.0/18' Public2: CIDR: '10.0.64.0/18' Private1: CIDR: '10.0.128.0/18' Private2: CIDR: '10.0.192.0/18' Resources: VPC: Type: 'AWS::EC2::VPC' Properties: CidrBlock: !FindInMap ['SubnetConfig', 'VPC', 'CIDR'] EnableDnsHostnames: true EnableDnsSupport: true InstanceTenancy: default PublicSubnet1: Type: 'AWS::EC2::Subnet' Properties: CidrBlock: !FindInMap ['SubnetConfig', 'Public1', 'CIDR'] VpcId: !Ref VPC AvailabilityZone: Fn::Select: - 0 - Fn::GetAZs: {Ref: 'AWS::Region'} MapPublicIpOnLaunch: true PublicSubnet1RouteTable: Type: 'AWS::EC2::RouteTable' Properties: VpcId: !Ref VPC PublicSubnet1RouteTableAssociation: Type: 'AWS::EC2::SubnetRouteTableAssociation' Properties: RouteTableId: !Ref PublicSubnet1RouteTable SubnetId: !Ref PublicSubnet1 PublicSubnet1DefaultRoute: Type: 'AWS::EC2::Route' Properties: RouteTableId: !Ref PublicSubnet1RouteTable DestinationCidrBlock: 0.0.0.0/0 GatewayId: !Ref InternetGateway DependsOn: - GatewayAttachement PublicSubnet1EIP: Type: 'AWS::EC2::EIP' Properties: Domain: vpc PublicSubnet1NATGateway: Type: 'AWS::EC2::NatGateway' Properties: SubnetId: !Ref PublicSubnet1 AllocationId: !GetAtt - PublicSubnet1EIP - AllocationId PublicSubnet2: Type: 'AWS::EC2::Subnet' Properties: CidrBlock: !FindInMap ['SubnetConfig', 'Public2', 'CIDR'] VpcId: !Ref VPC AvailabilityZone: Fn::Select: - 1 - Fn::GetAZs: {Ref: 'AWS::Region'} MapPublicIpOnLaunch: true PublicSubnet2RouteTable: Type: 'AWS::EC2::RouteTable' Properties: VpcId: !Ref VPC PublicSubnet2RouteTableAssociation: Type: 'AWS::EC2::SubnetRouteTableAssociation' Properties: RouteTableId: !Ref PublicSubnet2RouteTable SubnetId: !Ref PublicSubnet2 PublicSubnet2DefaultRoute: Type: 'AWS::EC2::Route' Properties: RouteTableId: !Ref PublicSubnet2RouteTable DestinationCidrBlock: 0.0.0.0/0 GatewayId: !Ref InternetGateway DependsOn: - GatewayAttachement PublicSubnet2EIP: Type: 'AWS::EC2::EIP' Properties: Domain: vpc PublicSubnet2NATGateway: Type: 'AWS::EC2::NatGateway' Properties: SubnetId: !Ref PublicSubnet2 AllocationId: !GetAtt - PublicSubnet2EIP - AllocationId PrivateSubnet1: Type: 'AWS::EC2::Subnet' Properties: CidrBlock: !FindInMap ['SubnetConfig', 'Private1', 'CIDR'] VpcId: !Ref VPC AvailabilityZone: Fn::Select: - 0 - Fn::GetAZs: {Ref: 'AWS::Region'} MapPublicIpOnLaunch: false PrivateSubnet1RouteTable: Type: 'AWS::EC2::RouteTable' Properties: VpcId: !Ref VPC PrivateSubnet1RouteTableAssociation: Type: 'AWS::EC2::SubnetRouteTableAssociation' Properties: RouteTableId: !Ref PrivateSubnet1RouteTable SubnetId: !Ref PrivateSubnet1 PrivateSubnet1DefaultRoute: Type: 'AWS::EC2::Route' Properties: RouteTableId: !Ref PrivateSubnet1RouteTable DestinationCidrBlock: 0.0.0.0/0 NatGatewayId: !Ref PublicSubnet1NATGateway PrivateSubnet2: Type: 'AWS::EC2::Subnet' Properties: CidrBlock: !FindInMap ['SubnetConfig', 'Private2', 'CIDR'] VpcId: !Ref VPC AvailabilityZone: Fn::Select: - 1 - Fn::GetAZs: {Ref: 'AWS::Region'} MapPublicIpOnLaunch: false PrivateSubnet2RouteTable: Type: 'AWS::EC2::RouteTable' Properties: VpcId: !Ref VPC PrivateSubnet2RouteTableAssociation: Type: 'AWS::EC2::SubnetRouteTableAssociation' Properties: RouteTableId: !Ref PrivateSubnet2RouteTable SubnetId: !Ref PrivateSubnet2 PrivateSubnet2DefaultRoute: Type: 'AWS::EC2::Route' Properties: RouteTableId: !Ref PrivateSubnet2RouteTable DestinationCidrBlock: 0.0.0.0/0 NatGatewayId: !Ref PublicSubnet2NATGateway InternetGateway: Type: 'AWS::EC2::InternetGateway' GatewayAttachement: Type: 'AWS::EC2::VPCGatewayAttachment' Properties: VpcId: !Ref VPC InternetGatewayId: !Ref InternetGateway pingSNSTopic: Type: AWS::SNS::Topic Properties: TopicName: !Sub '${AWS::StackName}-ping' KmsMasterKeyId: 'alias/aws/sns' pingSNSTopicPolicy: Type: AWS::SNS::TopicPolicy DependsOn: pingSNSTopic Properties: Topics: - !Ref pingSNSTopic PolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Principal: AWS: !Sub 'arn:${AWS::Partition}:iam::${AWS::AccountId}:root' Action: - sns:Subscribe Resource: !Ref pingSNSTopic Condition: StringEquals: "sns:Protocol": "sqs" SNSVPCEndpoint: Type: AWS::EC2::VPCEndpoint Properties: PrivateDnsEnabled: Yes SecurityGroupIds: - !GetAtt VPC.DefaultSecurityGroup ServiceName: !Sub 'com.amazonaws.${AWS::Region}.sns' SubnetIds: - !Ref 'PublicSubnet1' - !Ref 'PublicSubnet2' VpcEndpointType: Interface VpcId: !Ref VPC ApprunnerVpcConnector: Type: AWS::AppRunner::VpcConnector Properties: VpcConnectorName: 'sample-env-vpc-connector' Subnets: - !Ref 'PublicSubnet1' - !Ref 'PublicSubnet2' SecurityGroups: - !GetAtt VPC.DefaultSecurityGroup Outputs: SNSTopicArn: Description: The name of the SNS Topic Value: !Ref 'pingSNSTopic' SNSTopicName: Description: TopicName of the SNS Topic Value: !GetAtt pingSNSTopic.TopicName SNSRegion: Description: Region of the SNS Topic Value: !Ref 'AWS::Region' VPC: Description: The ID of the VPC that this stack is deployed in Value: !Ref 'VPC' PublicSubnet1: Description: Public subnet one Value: !Ref 'PublicSubnet1' PublicSubnet2: Description: Public subnet two Value: !Ref 'PublicSubnet2' PrivateSubnet1: Description: Private subnet one Value: !Ref 'PrivateSubnet1' PrivateSubnet2: Description: Private subnet two Value: !Ref 'PrivateSubnet2' VPCSecurityGroup: Description: Default security group for VPC Value: !GetAtt VPC.DefaultSecurityGroup VpcConnectorArn: Description: ARN of the VPC connector Value: !GetAtt ApprunnerVpcConnector.VpcConnectorArn