A VPC is a private IPv4 range in one region; subnets divide it, each in one Availability Zone; a route table decides where each subnet's traffic may go. BookNest takes 10.20.0.0/16 and cuts four /24 subnets, a public and a private one in each of two zones, so losing a zone leaves a working copy. AWS 24 reserves five addresses per subnet, leaving 251. Avoid ranges of networks you may connect later:
Vpc:
Type: AWS::EC2::VPC
Properties:
CidrBlock: 10.20.0.0/16
Tags: [{Key: Name, Value: booknest-vpc}]
InternetGateway:
Type: AWS::EC2::InternetGateway
GatewayAttachment:
Type: AWS::EC2::VPCGatewayAttachment
Properties: {VpcId: !Ref Vpc, InternetGatewayId: !Ref InternetGateway}
PublicSubnetA:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref Vpc
CidrBlock: 10.20.0.0/24
AvailabilityZone: !Select [0, !GetAZs ""]PrivateSubnetA (10.20.10.0/24), PublicSubnetB (10.20.1.0/24) and PrivateSubnetB (10.20.11.0/24) follow (Fn::Cidr could compute them, but 4.13.1 lacks it). A subnet is public only because its route table sends 0.0.0.0/0 to the internet gateway. The private table has no such route and no NAT gateway (Real AWS Costs); the API reaches DynamoDB 24 through a free gateway endpoint, which routes DynamoDB's prefix list:
PublicRouteTable:
Type: AWS::EC2::RouteTable
Properties: {VpcId: !Ref Vpc}
DefaultRoute:
Type: AWS::EC2::Route
DependsOn: GatewayAttachment
Properties:
RouteTableId: !Ref PublicRouteTable
DestinationCidrBlock: 0.0.0.0/0
GatewayId: !Ref InternetGateway
PrivateRouteTable:
Type: AWS::EC2::RouteTable
Properties: {VpcId: !Ref Vpc}
DynamoDbEndpoint:
Type: AWS::EC2::VPCEndpoint
Properties:
VpcId: !Ref Vpc
ServiceName: !Sub com.amazonaws.${AWS::Region}.dynamodb
VpcEndpointType: Gateway
RouteTableIds: [!Ref PrivateRouteTable]Four SubnetRouteTableAssociation resources tie the subnets to their tables. DependsOn is needed because the route never mentions the attachment, yet fails if the gateway is not attached yet (Dependency Graph).