Skip to content

Networking

Virtual Private Cloud

To contain everything in our AWS account, we'll create a Virtual Private Cloud (VPC). This is the container for virtually everything we're going to create in AWS such as our subnets, route tables, EC2 instances, and anything else we create in the future. The VPC essentially defines the network block that we're going to be working inside of. It's the biggest unit of networking space we define and everything else goes inside of it.

It goes without saying that AWS have excellent documentation on their VPC solution.

Note

We're about to start seeing Terraform code - don't worry about writing it down or copying it for now. We'll do that later, I promise. Also any code you'll see through this "Architecture" section is just example code from the Terraform documentation. It's not configured for our workload.

To create a VPC in AWS we're going to need an aws_vpc resource in our Terraform code:

1
2
3
resource "aws_vpc" "main" {
  cidr_block = "10.1.0.0/16"
}

Here's what this would look like in the VPC section of the AWS Console (Services -> VPC)...

AWS Example VPC

For our VPC to be usable we're going to have to create some subnets, which allow us to further "slice up" a VPC into smaller network segments we can use to contain workloads.

Subnets

These are isolated, segmented parts of the VPC. They're smaller than the VPC network and are used to securely contain workloads inside of their own network segment. We're only going to be working with two subnets at this point in time, but we'll add more as the HTTP Cats solution gets more complicated.

In Terraform we use an aws_subnet resource to create a subnet inside of a VPC:

1
2
3
4
resource "aws_subnet" "main" {
  vpc_id     = aws_vpc.main.id
  cidr_block = "10.1.1.0/24"
}

Note

Notice how the subnet uses our example VPC above - aws_vpc.main - as a reference? This allows us to easily link the two resources inside of Terraform and create a dependency.

Here we're defining a simple subnet inside of our VPC and creating a /24 network. That means we get approx. 255 IPv4 addresses we can use (it's actually less than that, but let's keep this simple for now.)

Route Tables

A route table is a set of rules that we attach to a subnet so that traffic from inside that subnet knows how-to access other subnets, the Internet, and more. We define a simple, custom route table that allows our subnets to route traffic to other systems inside the same subnet, other subnets inside the VPC, and out to the public Internet via an Internet Gateway.

We will have to create an aws_route_table in Terraform to set up our Route Tables in AWS:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
resource "aws_route_table" "example" {
  vpc_id = aws_vpc.main.id

  route = [
    {
      cidr_block = "0.0.0.0/0"
      gateway_id = aws_internet_gateway.example.id
    }
  ]
}

This simple aws_route_table will allow our subnets to route traffic between hosts inside the subnet and traffic out of the subnet and to other hosts on the public Internet (using either an Internet gateway or a NAT Gateway, or some other mechanism for bridging the gap between our VPC and the Internet.)

Network Access Control List (NACL)

A NACL is a security rule that defines what traffic can flow in and our of a subnet. It's a firewall, essentially, but it's different to a Security Group (discussed later) because it operates at a different networking layer and it's not stateful.

We're not going to be creating any NACLs in our Terraform code. Instead AWS' will provide us with default NACLs that allow all traffic into and out of a subnet. This isn't best practice in production environments, but there's more to understand about networking in AWS before we introduce NACLs. That being said, here is a simple diagram demonstrating where a NACL sits in the network, with regards to traffic flow, versus a Security Group:

graph LR

  client -- Packet --> nacl
  nacl -- Packet --> subnet
  subnet -- Packet --> sg
  sg -- Packet --> instance

  client[Client]
  nacl[NACL]
  subnet[Subnet]
  sg[Security Group]
  instance[EC2 Instance]

Internet Gateway

Although not visually demonstrated on the diagram, we're also going to need an Internet Gateway (IGW). This is used for routing traffic between the public Internet and our internal servers inside of their subnets:

graph LR
    A[Internet] -- Traffic --> B[Internet Gateway]
    B --> C[VPC]
    C --> D[Subnet]
    C --> E[Subnet]
    C --> F[Subnet]

And back again:

graph RL
    B[Internet Gateway] -->  A[Internet]
    C[VPC] --> B
    D[Subnet] -- Traffic --> C
    E[Subnet] -- Traffic --> C
    F[Subnet] -- Traffic --> C

In Terraform we create an aws_internet_gateway and attach it to a VPC:

1
2
3
resource "aws_internet_gateway" "example" {
  vpc_id = aws_vpc.main.id
}

We can this use this Internet Gateway inside of our Route Tables (above) to allow traffic in to and out of our VPC and towards the public Internet.

Implementation Details

Now we're going to generate some technical documentation in the form of tables that will help us nail downn the specifics of our VPC, subnets, route tables, and more.

VPC

Name Description CIDR Hosts
httpcats-vpc The VPC for our entire solution 10.1.1.0/24 250

Subnets

| Name | Description | CIDR | Hosts | Availability Zone | | application-subnet-a | An application subnet | 10.1.1.0/27 | 25 | A | | application-subnet-b | An application subnet | 10.1.1.32/27 | 25 | B |


Last update: September 14, 2021