By Olivier Robert, a Senior Consultant and DevOps Engineer at Agile Partner.
In Part1, we worked on a template to create a VPC. We will extend this template with subnets and route tables. We’ll have public and private subnets.
Private subnets will be used for everything we want to shield from a direct internet access.
Public subnets means we want to be able to connect to services directly over an internet connection.
Our VPC will need an internet gateway. The default routing for our public subnet will be the Intenet Gateway.
Private subnets can be accessed from public subnets or services if this is what we want, but they will have no routing to the Internet Gateway and thus not internet access inbound, or outbound. An EC2 instance deployed in a private subnet will not be able to get updates from the internet for example. To remedy this situation, we can use a NAT Gateway.
The Nat Gateway, deployed in the public subnet, will relay internet connections initiated from the private subnet to the internet via the Internet Gateway. But there is still no way to directly connect from the internet to the private subnet. This is what we want.
Routing. We will have to create route tables and default routings and then associate public and private subnets to specific routing tables.
If you have read until here, have a look at this AWS scenario. It will clear things up.
Mmmm, one more thing, we will use Availability Zones to our advantage and distribute our subnets so that they are not all created in the same AZ.
Adding an Internet Gateway is straight forward:
The NAT Gateway will need an Elastic IP allocated to it.
Domain is set to vpc to allocate the address for use with instances in a VPC. In our case, the NAT Gateway.
We use the intrinsic function GetAtt to retrieve the allocation ID attribute from the Elastic IP resource we named EIP.
For the subnet in which the NAT Gateway should be deployed in, we use the Ref intrinsic function to reference a public subnet. That public subnet has not been defined yet, but we will name it “VPCPublicSubnet1”.
For now, we’ll continue with the NAT Gateway and attach it to our VPC and specify the Internet Gateway.
Notice that we use resource references.
If you wonder how resources are created, Cloudformation creates independent resources in parallel. Implicit dependencies are detected when the property of one resource is referring to another resource (for instance an Internet Gateway in a VPCGatewayAttachment). Explicit dependencies can be declared with the DependsOn attribute. When we are using Ref to reference resources, we are creating implicit dependencies. The referenced resources should be created first. Sometimes, when things get complicated, explicit dependencies can solve issues.
In public subnets, we’ll want automatic public IP allocations and as we are going to create 3 public subnets, we will distribute them over Availability Zones.
Remember our NAT Gateway resource? Now the reference to VPCPublicSubnet1 is valid.
MapPublicIpOnLaunch is useful because instances launched in public subnets will get a public IP automatically.
The GetAZs intrisic function returns an array of Availability Zones. We just pick one in the array for each subnet with Select.
We introduced PublicSubnet<#>CIDR which does not exist yet! These are references to parameters. Let’s sort this out.
I added parameter labels as well in the metadata section.
Next, private subnets where we do not need public adresses.
So far, our entire template looks like this:
Note that we have indicated default CIDR values for the subnets to avoid typing all parameters by hand in the web interface. The only thing we need to enter manually when creating the stack is a stack name.
It’s time to get the routing part done. We will create a route table and a default route. Our route table only needs a reference to a VPC.
Our default route will route any traffic to the internet gateway:
This public route table (containing the default route) needs to be associated with the public subnets.
We will do the same for the private subnet except these subnet will have a default route routing to the NAT Gateway.
Our final VPC template is this:
If you haven’t uploaded the template to Cloudformation, here is the parameters section you’d get before launching it.
Stay tuned for Part 3 where we will deploy an EC2 bastion host in the public subnet and an EC2 instance in the private subnets to validate our configuration.