AWSTemplateFormatVersion: "2010-09-09" Description: >- This template creates a Multi-AZ, multi-subnet VPC infrastructure with managed NAT gateways in the public subnet for each Availability Zone. You can also create additional private subnets with dedicated custom network access control lists (ACLs). If you deploy the Quick Start in a region that doesn't support NAT gateways, NAT instances are deployed instead. **WARNING** This template creates AWS resources. You will be billed for the AWS resources used if you create a stack from this template. (qs-1qnnspaap) Metadata: QuickStartDocumentation: EntrypointName: "Launch a New VPC" OptionalParameters: - PrivateSubnetATag1 - PrivateSubnetATag2 - PrivateSubnetATag3 - PrivateSubnetBTag1 - PrivateSubnetBTag2 - PrivateSubnetBTag3 - PublicSubnetTag1 - PublicSubnetTag2 - PublicSubnetTag3 AWS::CloudFormation::Interface: ParameterGroups: - Label: default: Availability Zone Configuration Parameters: - AvailabilityZones - Label: default: Network Configuration Parameters: - VPCCIDR - PublicSubnet1CIDR - PublicSubnet2CIDR - PublicSubnetTag1 - PrivateSubnet1ACIDR - PrivateSubnet2ACIDR - PrivateSubnetATag1 - VPCTenancy ParameterLabels: AvailabilityZones: default: Availability Zones PrivateSubnet1ACIDR: default: Private subnet 1A CIDR PrivateSubnet2ACIDR: default: Private subnet 2A CIDR PrivateSubnetATag1: default: Tag for Private A Subnets PublicSubnet1CIDR: default: Public subnet 1 CIDR PublicSubnet2CIDR: default: Public subnet 2 CIDR PublicSubnetTag1: default: Tag for Public Subnets VPCCIDR: default: VPC CIDR VPCTenancy: default: VPC Tenancy Parameters: AvailabilityZones: Description: "List of Availability Zones to use for the subnets in the VPC. Note: The logical order is preserved." Type: List PrivateSubnet1ACIDR: AllowedPattern: ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/(1[6-9]|2[0-8]))$ ConstraintDescription: CIDR block parameter must be in the form x.x.x.x/16-28 Default: 10.0.0.0/19 Description: CIDR block for private subnet 1A located in Availability Zone 1 Type: String PrivateSubnet2ACIDR: AllowedPattern: ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/(1[6-9]|2[0-8]))$ ConstraintDescription: CIDR block parameter must be in the form x.x.x.x/16-28 Default: 10.0.32.0/19 Description: CIDR block for private subnet 2A located in Availability Zone 2 Type: String PrivateSubnetATag1: AllowedPattern: ^([a-zA-Z0-9+\-._:/@]+=[a-zA-Z0-9+\-.,_:/@ *\\"'\[\]\{\}]*)?$ ConstraintDescription: tags must be in format "Key=Value" keys can only contain [a-zA-Z0-9+\-._:/@], values can contain [a-zA-Z0-9+\-._:/@ *\\"'\[\]\{\}] Default: Network=Private Description: tag to add to private subnets A, in format Key=Value (Optional) Type: String PublicSubnet1CIDR: AllowedPattern: ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/(1[6-9]|2[0-8]))$ ConstraintDescription: CIDR block parameter must be in the form x.x.x.x/16-28 Default: 10.0.128.0/20 Description: CIDR block for the public DMZ subnet 1 located in Availability Zone 1 Type: String PublicSubnet2CIDR: AllowedPattern: ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/(1[6-9]|2[0-8]))$ ConstraintDescription: CIDR block parameter must be in the form x.x.x.x/16-28 Default: 10.0.144.0/20 Description: CIDR block for the public DMZ subnet 2 located in Availability Zone 2 Type: String PublicSubnetTag1: AllowedPattern: ^([a-zA-Z0-9+\-._:/@]+=[a-zA-Z0-9+\-.,_:/@ *\\"'\[\]\{\}]*)?$ ConstraintDescription: tags must be in format "Key=Value" keys can only contain [a-zA-Z0-9+\-._:/@], values can contain [a-zA-Z0-9+\-._:/@ *\\"'\[\]\{\}] Default: Network=Public Description: tag to add to public subnets, in format Key=Value (Optional) Type: String VPCCIDR: AllowedPattern: ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/(1[6-9]|2[0-8]))$ ConstraintDescription: CIDR block parameter must be in the form x.x.x.x/16-28 Default: 10.0.0.0/16 Description: CIDR block for the VPC Type: String VPCTenancy: AllowedValues: - default - dedicated Default: default Description: The allowed tenancy of instances launched into the VPC Type: String Conditions: PrivateSubnetATag1Condition: !Not - !Equals - !Ref "PrivateSubnetATag1" - "" PublicSubnetTag1Condition: !Not - !Equals - !Ref "PublicSubnetTag1" - "" Resources: DHCPOptions: Type: AWS::EC2::DHCPOptions Properties: DomainName: !Sub "${AWS::Region}.compute.internal" DomainNameServers: - AmazonProvidedDNS VPC: Type: AWS::EC2::VPC Properties: CidrBlock: !Ref "VPCCIDR" InstanceTenancy: !Ref "VPCTenancy" EnableDnsSupport: true EnableDnsHostnames: true Tags: - Key: Name Value: !Ref "AWS::StackName" VPCDHCPOptionsAssociation: Type: AWS::EC2::VPCDHCPOptionsAssociation Properties: VpcId: !Ref "VPC" DhcpOptionsId: !Ref "DHCPOptions" InternetGateway: Type: AWS::EC2::InternetGateway Properties: Tags: - Key: Name Value: !Ref "AWS::StackName" VPCGatewayAttachment: Type: AWS::EC2::VPCGatewayAttachment Properties: VpcId: !Ref "VPC" InternetGatewayId: !Ref "InternetGateway" PrivateSubnet1A: Type: AWS::EC2::Subnet Properties: VpcId: !Ref "VPC" CidrBlock: !Ref "PrivateSubnet1ACIDR" AvailabilityZone: !Select - "0" - !Ref "AvailabilityZones" Tags: - Key: Name Value: Private subnet 1A - !If - PrivateSubnetATag1Condition - Key: !Select - "0" - !Split - "=" - !Ref "PrivateSubnetATag1" Value: !Select - "1" - !Split - "=" - !Ref "PrivateSubnetATag1" - !Ref "AWS::NoValue" PrivateSubnet2A: Type: AWS::EC2::Subnet Properties: VpcId: !Ref "VPC" CidrBlock: !Ref "PrivateSubnet2ACIDR" AvailabilityZone: !Select - "1" - !Ref "AvailabilityZones" Tags: - Key: Name Value: Private subnet 2A - !If - PrivateSubnetATag1Condition - Key: !Select - "0" - !Split - "=" - !Ref "PrivateSubnetATag1" Value: !Select - "1" - !Split - "=" - !Ref "PrivateSubnetATag1" - !Ref "AWS::NoValue" PublicSubnet1: Type: AWS::EC2::Subnet Properties: VpcId: !Ref "VPC" CidrBlock: !Ref "PublicSubnet1CIDR" AvailabilityZone: !Select - "0" - !Ref "AvailabilityZones" Tags: - Key: Name Value: Public subnet 1 - !If - PublicSubnetTag1Condition - Key: !Select - "0" - !Split - "=" - !Ref "PublicSubnetTag1" Value: !Select - "1" - !Split - "=" - !Ref "PublicSubnetTag1" - !Ref "AWS::NoValue" MapPublicIpOnLaunch: true PublicSubnet2: Type: AWS::EC2::Subnet Properties: VpcId: !Ref "VPC" CidrBlock: !Ref "PublicSubnet2CIDR" AvailabilityZone: !Select - "1" - !Ref "AvailabilityZones" Tags: - Key: Name Value: Public subnet 2 - !If - PublicSubnetTag1Condition - Key: !Select - "0" - !Split - "=" - !Ref "PublicSubnetTag1" Value: !Select - "1" - !Split - "=" - !Ref "PublicSubnetTag1" - !Ref "AWS::NoValue" MapPublicIpOnLaunch: true PrivateSubnet1ARouteTable: Type: AWS::EC2::RouteTable Properties: VpcId: !Ref "VPC" Tags: - Key: Name Value: Private subnet 1A - Key: Network Value: Private PrivateSubnet1ARoute: Type: AWS::EC2::Route Properties: RouteTableId: !Ref "PrivateSubnet1ARouteTable" DestinationCidrBlock: "0.0.0.0/0" NatGatewayId: !Ref "NATGateway1" PrivateSubnet1ARouteTableAssociation: Type: AWS::EC2::SubnetRouteTableAssociation Properties: SubnetId: !Ref "PrivateSubnet1A" RouteTableId: !Ref "PrivateSubnet1ARouteTable" PrivateSubnet2ARouteTable: Type: AWS::EC2::RouteTable Properties: VpcId: !Ref "VPC" Tags: - Key: Name Value: Private subnet 2A - Key: Network Value: Private PrivateSubnet2ARoute: Type: AWS::EC2::Route Properties: RouteTableId: !Ref "PrivateSubnet2ARouteTable" DestinationCidrBlock: "0.0.0.0/0" NatGatewayId: !Ref "NATGateway2" PrivateSubnet2ARouteTableAssociation: Type: AWS::EC2::SubnetRouteTableAssociation Properties: SubnetId: !Ref "PrivateSubnet2A" RouteTableId: !Ref "PrivateSubnet2ARouteTable" PublicSubnetRouteTable: Type: AWS::EC2::RouteTable Properties: VpcId: !Ref "VPC" Tags: - Key: Name Value: Public Subnets - Key: Network Value: Public PublicSubnetRoute: DependsOn: VPCGatewayAttachment Type: AWS::EC2::Route Properties: RouteTableId: !Ref "PublicSubnetRouteTable" DestinationCidrBlock: "0.0.0.0/0" GatewayId: !Ref "InternetGateway" PublicSubnet1RouteTableAssociation: Type: AWS::EC2::SubnetRouteTableAssociation Properties: SubnetId: !Ref "PublicSubnet1" RouteTableId: !Ref "PublicSubnetRouteTable" PublicSubnet2RouteTableAssociation: Type: AWS::EC2::SubnetRouteTableAssociation Properties: SubnetId: !Ref "PublicSubnet2" RouteTableId: !Ref "PublicSubnetRouteTable" NAT1EIP: DependsOn: VPCGatewayAttachment Type: AWS::EC2::EIP Properties: Domain: vpc NAT2EIP: DependsOn: VPCGatewayAttachment Type: AWS::EC2::EIP Properties: Domain: vpc NATGateway1: DependsOn: VPCGatewayAttachment Type: AWS::EC2::NatGateway Properties: AllocationId: !GetAtt "NAT1EIP.AllocationId" SubnetId: !Ref "PublicSubnet1" NATGateway2: DependsOn: VPCGatewayAttachment Type: AWS::EC2::NatGateway Properties: AllocationId: !GetAtt "NAT2EIP.AllocationId" SubnetId: !Ref "PublicSubnet2" S3VPCEndpoint: Type: AWS::EC2::VPCEndpoint Properties: PolicyDocument: Version: "2012-10-17" Statement: - Action: "*" Effect: Allow Resource: "*" Principal: "*" RouteTableIds: - !Ref "PrivateSubnet1ARouteTable" - !Ref "PrivateSubnet2ARouteTable" ServiceName: !Sub "com.amazonaws.${AWS::Region}.s3" VpcId: !Ref "VPC" Outputs: NAT1EIP: Description: NAT 1 IP address Value: !Ref "NAT1EIP" Export: Name: !Sub "${AWS::StackName}-NAT1EIP" NAT2EIP: Description: NAT 2 IP address Value: !Ref "NAT2EIP" Export: Name: !Sub "${AWS::StackName}-NAT2EIP" PrivateSubnet1ACIDR: Description: Private subnet 1A CIDR in Availability Zone 1 Value: !Ref "PrivateSubnet1ACIDR" Export: Name: !Sub "${AWS::StackName}-PrivateSubnet1ACIDR" PrivateSubnet1AID: Description: Private subnet 1A ID in Availability Zone 1 Value: !Ref "PrivateSubnet1A" Export: Name: !Sub "${AWS::StackName}-PrivateSubnet1AID" PrivateSubnet2ACIDR: Description: Private subnet 2A CIDR in Availability Zone 2 Value: !Ref "PrivateSubnet2ACIDR" Export: Name: !Sub "${AWS::StackName}-PrivateSubnet2ACIDR" PrivateSubnet2AID: Description: Private subnet 2A ID in Availability Zone 2 Value: !Ref "PrivateSubnet2A" Export: Name: !Sub "${AWS::StackName}-PrivateSubnet2AID" PublicSubnet1CIDR: Description: Public subnet 1 CIDR in Availability Zone 1 Value: !Ref "PublicSubnet1CIDR" Export: Name: !Sub "${AWS::StackName}-PublicSubnet1CIDR" PublicSubnet1ID: Description: Public subnet 1 ID in Availability Zone 1 Value: !Ref "PublicSubnet1" Export: Name: !Sub "${AWS::StackName}-PublicSubnet1ID" PublicSubnet2CIDR: Description: Public subnet 2 CIDR in Availability Zone 2 Value: !Ref "PublicSubnet2CIDR" Export: Name: !Sub "${AWS::StackName}-PublicSubnet2CIDR" PublicSubnet2ID: Description: Public subnet 2 ID in Availability Zone 2 Value: !Ref "PublicSubnet2" Export: Name: !Sub "${AWS::StackName}-PublicSubnet2ID" S3VPCEndpoint: Description: S3 VPC Endpoint Value: !Ref "S3VPCEndpoint" Export: Name: !Sub "${AWS::StackName}-S3VPCEndpoint" PrivateSubnet1ARouteTable: Value: !Ref "PrivateSubnet1ARouteTable" Description: Private subnet 1A route table Export: Name: !Sub "${AWS::StackName}-PrivateSubnet1ARouteTable" PrivateSubnet2ARouteTable: Value: !Ref "PrivateSubnet2ARouteTable" Description: Private subnet 2A route table Export: Name: !Sub "${AWS::StackName}-PrivateSubnet2ARouteTable" PublicSubnetRouteTable: Value: !Ref "PublicSubnetRouteTable" Description: Public subnet route table Export: Name: !Sub "${AWS::StackName}-PublicSubnetRouteTable" VPCCIDR: Value: !Ref "VPCCIDR" Description: VPC CIDR Export: Name: !Sub "${AWS::StackName}-VPCCIDR" VPCID: Value: !Ref "VPC" Description: VPC ID Export: Name: !Sub "${AWS::StackName}-VPCID"