Creating a VPC

In this section, we will create a VPC consisting of two private and two public subnets. Both subnets will be distributed among two availability zone in the region our application works. From the AWS perspective, it is a good idea to remind that all subnets are just a pool of IP addresses. What makes a subnet public is a routing rule that routes traffic to Internet Gateway. Internet Gateway is also a AWS component that bridges outer internet with our VPC.

We will then install two NAT Gateways on both public subnets. Both private subnets will have a routing rule that moves the outgoing internet traffic to NAT Gateway, so NAT Gateways can enable communication between those private subnets with outer Internet. On the other hand, resources in the private subnet will not be accessible from outer internet, so they will stay secure. We will create two Elastic IPs which are available from internet. These IP addresses will be assigned to NAT Gateways. Whenever a host in a private subnet accesses internet resource, the traffic will be seen as originating from those Elastic IP addresses. It means that we need to give those IP addresses to other teams if we want them to allow their service to access our application.

NAT Gateways are billed per hour and data transfer. Whenever you create them you will be started to billed, so when you do not need them, remove them. We could also create only one NAT Gateway and share it between two private subnets. This is possible and might seem a cheaper solution. On the other hand, if the region where NAT Gateway goes down, that your application will lose Internet connectivity. That's why we play it safe and create two NAT Gateways.

Now let's start to create our VPC config. This part may seem a bit complicated if you do not have networking knowledge. If you do not understand any term you can refer to the AWS VPC documentation.

To start the VPC configuration, first we need to add a VPC itself:

"VPC": { 
  "Type": "AWS::EC2::VPC", 
    "Properties": { 
      "CidrBlock": "10.0.0.0/16", 
      "Tags": [ 
        { 
          "Key": "Name", 
          "Value": { 
            "Fn::Sub": "${AWS::StackName}: VPC" 
          } 
        } 
      ] 
   } 
} 

Our VPC will span 10.0.0.0/16 IP Block. As you know from CIDR notation, this IP range starts from 10.0.0.0 and ends at 10.0.255.255, meaning that our subnets under this VPC should be inside this range.