AWSTemplateFormatVersion: "2010-09-09" Description: Simple Spoke VPC with Transit Gateway Attachment for Lab Environment Parameters: TransitGatewayId: Type: String Description: Transit Gateway ID from Networking Account (e.g., tgw-xxxxxxxx) AllowedPattern: ^tgw-[0-9a-f]{8,17}$ ConstraintDescription: Must be a valid Transit Gateway ID VpcCidr: Type: String Default: 10.1.0.0/16 Description: CIDR block for Spoke VPC 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])(\/([0-9]|[1-2][0-9]|3[0-2]))$ ConstraintDescription: Must be a valid IP CIDR range PrivateSubnetCidr: Type: String Default: 10.1.1.0/24 Description: CIDR block for private subnet in spoke VPC 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])(\/([0-9]|[1-2][0-9]|3[0-2]))$ ConstraintDescription: Must be a valid IP CIDR range Resources: # VPC SpokeVPC: Type: AWS::EC2::VPC Properties: CidrBlock: !Ref VpcCidr EnableDnsHostnames: true EnableDnsSupport: true Tags: - Key: Name Value: sanbox-spoke-vpc - Key: Environment Value: lab # Private Subnet PrivateSubnet: Type: AWS::EC2::Subnet Properties: VpcId: !Ref SpokeVPC CidrBlock: !Ref PrivateSubnetCidr AvailabilityZone: !Select [0, !GetAZs ""] MapPublicIpOnLaunch: false Tags: - Key: Name Value: sandbox-private-subnet # Transit Gateway Attachment TransitGatewayAttachment: Type: AWS::EC2::TransitGatewayVpcAttachment Properties: TransitGatewayId: !Ref TransitGatewayId VpcId: !Ref SpokeVPC SubnetIds: - !Ref PrivateSubnet Tags: - Key: Name Value: sandbox-spoke-tgw-attachment # Route Table PrivateRouteTable: Type: AWS::EC2::RouteTable Properties: VpcId: !Ref SpokeVPC Tags: - Key: Name Value: sandbox-private-rt # Route Table Association PrivateSubnetRouteTableAssociation: Type: AWS::EC2::SubnetRouteTableAssociation Properties: RouteTableId: !Ref PrivateRouteTable SubnetId: !Ref PrivateSubnet # Routes - All traffic through Transit Gateway DefaultRouteToTGW: Type: AWS::EC2::Route DependsOn: TransitGatewayAttachment Properties: RouteTableId: !Ref PrivateRouteTable DestinationCidrBlock: 0.0.0.0/0 TransitGatewayId: !Ref TransitGatewayId Outputs: SpokeVpcId: Description: Spoke VPC ID for Lab Value: !Ref SpokeVPC Export: Name: !Sub "${AWS::StackName}-VpcId" PrivateSubnetId: Description: Private Subnet ID Value: !Ref PrivateSubnet Export: Name: !Sub "${AWS::StackName}-PrivateSubnetId" TransitGatewayAttachmentId: Description: Transit Gateway VPC Attachment ID Value: !Ref TransitGatewayAttachment Export: Name: !Sub "${AWS::StackName}-TGWAttachmentId" VpcCidr: Description: VPC CIDR Block Value: !Ref VpcCidr Export: Name: !Sub "${AWS::StackName}-VpcCidr"