This is part 03 in this series. Previously in
Part 01 – I created a VPC, and internet gateway and attached the internet gateway to the VPC
Part 02 – I added a public and private subnet in one availability zone
In this part, I am adding
– an EIP for the NAT gateway,
– a NAT gateway
– public and private route tables with default routes, and
– associating the route tables with their respective subnets.
The complete (includes all parts 01-03) code is below:
AWSTemplateFormatVersion: '2010-09-09'
#
## The Description section (optional) enables you to include comments about your template.
#
Description:
Create VPC, and related components
#
## Parameters section to customize your templates
#
Parameters:
VPCName:
Description: Name of the VPC
Type: String
Default: "MyVPC"
MinLength: '1'
MaxLength: '30'
AllowedPattern: '^[a-zA-Z]+[0-9a-zA-Z\-]*$'
ConstraintDescription: Must contain alphabets and/or numbers.
VpcCIDR:
Description: Please enter the IP range (CIDR notation) for this VPC
Type: String
Default: 10.0.0.0/16
MinLength: '10'
MaxLength: '18'
AllowedPattern: "(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})/(\\d{1,2})"
ConstraintDescription: Must be a valid CIDR range of the form x.x.x.x/x.
PublicSubnet1CIDR:
Description: Please enter the IP range (CIDR notation) for the public subnet in the first Availability Zone
Type: String
Default: 10.0.1.0/24
MinLength: '10'
MaxLength: '18'
AllowedPattern: "(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})/(\\d{1,2})"
ConstraintDescription: Must be a valid CIDR range of the form x.x.x.x/x.
PrivateSubnet1CIDR:
Description: Please enter the IP range (CIDR notation) for the private subnet in the first Availability Zone
Type: String
Default: 10.0.3.0/24
MinLength: '10'
MaxLength: '18'
AllowedPattern: "(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})/(\\d{1,2})"
ConstraintDescription: Must be a valid CIDR range of the form x.x.x.x/x.
#
## Resources created by the stack
#
Resources:
#
## Create the VPC
##
## Uses the intrinsic function Ref to get the value of the VPC Name
## from parameters above
#
VPC:
Type: AWS::EC2::VPC
Properties:
CidrBlock: !Ref VpcCIDR
EnableDnsSupport: true
EnableDnsHostnames: true
Tags:
- Key: Name
Value: !Ref VPCName
#
## Create the IGW
#
InternetGateway:
Type: AWS::EC2::InternetGateway
Properties:
Tags:
- Key: Name
Value: !Ref VPCName
#
## Connect the IGW to the VPC
#
InternetGatewayAttachment:
Type: AWS::EC2::VPCGatewayAttachment
Properties:
InternetGatewayId: !Ref InternetGateway
VpcId: !Ref VPC
#
## Create a public subnet
##
## The VpcId is obtained by referring back to the VPC created above
##
## The CIDR block is from the parameters
##
## The Availability Zone is obtained by querying the available availability
## zones in this region and returning the first (offset 0) entry
##
## The MapPublicIpOnLaunch is set to true indicating that instances launched
## in this subnet receive a public IPv4 address
#
PublicSubnet1:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref VPC
AvailabilityZone: !Select [ 0, !GetAZs '' ]
CidrBlock: !Ref PublicSubnet1CIDR
MapPublicIpOnLaunch: true
Tags:
- Key: Name
Value: !Sub ${VPCName} Public Subnet (AZ1)
#
## Create a private subnet
##
## The MapPublicIpOnLaunch is set to false indicating that instances launched
## in this subnet will not receive a public IPv4 address
#
PrivateSubnet1:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref VPC
AvailabilityZone: !Select [ 0, !GetAZs '' ]
CidrBlock: !Ref PrivateSubnet1CIDR
MapPublicIpOnLaunch: false
Tags:
- Key: Name
Value: !Sub ${VPCName} Private Subnet (AZ1)
#
## Create an Elastic IP (EIP) address
##
## The below section also uses the DependsOn attribute. With the DependsOn
## attribute you can specify that the creation of a specific resource follows
## another. When you add a DependsOn attribute to a resource, that resource is
## created only after the creation of the resource specified in the DependsOn
## attribute. In this case the NAT Gateway is dependent on the prior creation
## of the InternetGatewayAttachment and the attachment to the VPC
#
NatGateway1EIP:
Type: AWS::EC2::EIP
DependsOn: InternetGatewayAttachment
Properties:
Domain: vpc
Tags:
- Key: Name
Value: !Sub ${VPCName} NatGateway1 EIP
#
## Create a NAT GW
##
## Connect the EIP created above to the NAT GW
##
## Default to public connectivity
##
## Connecting to the subnet by using the parameter
#
NatGateway1:
Type: AWS::EC2::NatGateway
Properties:
AllocationId: !GetAtt NatGateway1EIP.AllocationId
SubnetId: !Ref PublicSubnet1
Tags:
- Key: Name
Value: !Sub ${VPCName} NatGateway 1
#
## Create a public route table
#
PublicRouteTable1:
Type: AWS::EC2::RouteTable
Properties:
VpcId: !Ref VPC
Tags:
- Key: Name
Value: !Sub ${VPCName} Public Routes
#
## Add a public route in the above route table to allow the
## subnets to access the internet through the IGW
#
DefaultPublicRoute:
Type: AWS::EC2::Route
DependsOn: InternetGatewayAttachment
Properties:
RouteTableId: !Ref PublicRouteTable1
DestinationCidrBlock: 0.0.0.0/0
GatewayId: !Ref InternetGateway
#
## Associate the public route tables with the public subnets
#
PublicSubnet1RouteTableAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
RouteTableId: !Ref PublicRouteTable1
SubnetId: !Ref PublicSubnet1
#
## Create a private route table
#
PrivateRouteTable1:
Type: AWS::EC2::RouteTable
Properties:
VpcId: !Ref VPC
Tags:
- Key: Name
Value: !Sub ${VPCName} Private Routes (AZ1)
#
## Add a route in the above route table to allow the
## subnets to access the internet through the IGW
#
DefaultPrivateRoute1:
Type: AWS::EC2::Route
Properties:
RouteTableId: !Ref PrivateRouteTable1
DestinationCidrBlock: 0.0.0.0/0
NatGatewayId: !Ref NatGateway1
#
## Associate the private route tables with the private subnets
#
PrivateSubnet1RouteTableAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
RouteTableId: !Ref PrivateRouteTable1
SubnetId: !Ref PrivateSubnet1
#
## Resources created by the stack
##
## Uses the intrinsic function Sub to get the stack name
## from parameters above and substitute it into the name of
## the internet gateway
#
Outputs:
VPC:
Description: Name of the VPC
Value: !Ref VPC
Export:
Name: !Sub '${AWS::StackName}'
InternetGateway:
Description: Internet Gateway
Value: !Ref InternetGateway
Export:
Name: !Sub '${AWS::StackName}-InternetGateway'
PublicSubnet1:
Description: AZ1 - public subnet
Value: !Ref PublicSubnet1
Export:
Name: !Sub '${AWS::StackName}-PublicSubnet1'
PrivateSubnet1:
Description: AZ1 - private subnet 01
Value: !Ref PrivateSubnet1
Export:
Name: !Sub '${AWS::StackName}-PrivateSubnet1'
NatGateway1EIP:
Description: NAT Gateway EIP
Value: !Ref NatGateway1EIP
Export:
Name: !Sub '${AWS::StackName}-NatGateway1EIP'
NatGateway1:
Description: NAT Gateway 1
Value: !Ref NatGateway1
Export:
Name: !Sub '${AWS::StackName}-NatGateway1'
PublicRouteTable1:
Description: Public route table
Value: !Ref PublicRouteTable1
Export:
Name: !Sub '${AWS::StackName}-PublicRouteTable1'
PrivateRouteTable1:
Description: Private route table - AZ1 - private subnet 01
Value: !Ref PrivateRouteTable1
Export:
Name: !Sub '${AWS::StackName}-PrivateRouteTable1'