AWS VPC 101
Tags: devops, sre, vpc, subnet
Published: 2020-07-10 10:20:03

AWS VPC is the foundation of cloud infrastructure in AWS. When we start architecting infrastructure, we start by designing the VPCs. Whatever we need to launch, EC2/EKS/RDS, we have to launch within the VPC. If we don't plan it well, soon we will be running out the IP address or facing subnet collision while setting up network connectivity with internal/external networks. So, we will try to have a high-level idea over AWS VPC in this blog.

## What is VPC?

> A _virtual private cloud_ (VPC) is a virtual network dedicated to your AWS account. It is logically isolated from other virtual networks in the AWS Cloud. You can launch your AWS resources, such as Amazon EC2 instances, into your VPC. You can specify an IP address range for the VPC, add subnets, associate security groups, and configure route tables.

AWS VPC is like a virtual router. If we connect two of our laptops with a router, we can reach out to each other (if there's no firewall hassle) and can access public internet (if internet connectivity is established with the router). This is a high-level concept.

![AWS VPC](https://docs.aws.amazon.com/vpc/latest/userguide/images/VPC-share-internet-gateway-example.png)

Points to be noted:

* Each VPC is logically isolated from other virtual networks in the AWS Cloud.
* Resources in a VPC can reach out to each other if there is no firewall (security group) hassle.
* Resources from one VPC can't reach out to other resources of different VPC normally. VPC Peering is required for that.
* A VPC spans all of the [Availability Zones](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-regions-availability-zones.html) in the Region.

### How to create a VPC?

When we create a VPC, we have to define a range of IPv4 addresses in the form of the CIDR (Classless Inter-Domain Routing) block. For example: `10.0.0.0/16` is a CIDR block that holds 65,536 IPv4 addresses.

We were talking VPC as a router, right? This CIDR block is required to define the network of the router. But we can't define network whatever we want. The allowed block size is between a `/16` netmask (65,536 IP addresses) and `/28` netmask (16 IP addresses). Apart from that, AWS recommends that we specify a CIDR block (of `/16` or smaller) from the private IPv4 address ranges as specified in [RFC 1918](http://www.faqs.org/rfcs/rfc1918.html):

* `10.0.0.0` - `10.255.255.255` (`10.0.0.0/8`)
* `172.16.0.0` - `172.31.255.255` (`172.16.0.0/12`)
* `192.168.0.0` - `192.168.255.255` (`192.168.0.0/16`)

Points to be noted:

* After we've created our VPC, we can associate secondary CIDR blocks with the VPC.
* We can create a VPC with a publicly routable CIDR block that falls outside of the private IPv4 address ranges specified in [RFC 1918](http://www.faqs.org/rfcs/rfc1918.html).

## What is Subnet?

> A _subnet_ is a range of IP addresses in your VPC. You can launch AWS resources into a specified subnet. Use a public subnet for resources that must be connected to the internet, and a private subnet for resources that won't be connected to the internet .

A subnet is a smaller sub-network in our VPC. When we create a VPC, we break down it into more than one smaller logical sub-networks. Unlike VPC, a subnet relies on only one [availability zone](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-regions-availability-zones.html). When we create a subnet, we add it to an availability zone.

![AWS VPC & Subnets](https://docs.aws.amazon.com/vpc/latest/userguide/images/nondefault-vpc-diagram.png)

Previously we considered `10.0.0.0/16` as our VPC. We can break down this CIDR into smaller blocks and declare them as our subnet. Example:

* **Subnet-1**: `10.0.0.0/24` (256 IPv4 addresses)
* **Subnet-2**: `10.0.1.0/24` (256 IPv4 addresses)
* **Subnet-3**: `10.0.2.0/24` (256 IPv4 addresses)
* **Subnet-4**: `10.0.3.0/24` (256 IPv4 addresses)

Here, we have broken down our VPC into 4 similar sizes of subnets. But that is not required. We can choose to have any size of the subnet that fits well into our VPC.

### Public Subnet

> If a subnet's traffic is routed to an internet gateway, the subnet is known as a _public subnet_.

An internet gateway (IGW) is attached to a public subnet. Any resource within a public subnet directly communicates with the internet through that IGW.

![Public Subnet](https://docs.aws.amazon.com/vpc/latest/userguide/images/internet-gateway-overview-diagram.png)

From our previous example, we can attach two internet gateways to **Subnet-1** and **Subnet-3**. Then these subnets will be considered as public subnets. It is recommended to create subnets in multiple availability zones. So, we may create **Subnet-1** in Zone-A and **Subnet-3** in Zone-B.

Points to be noted:

* If we want our instance in a public subnet to communicate with the internet over IPv4, it must have a public IPv4 address or an Elastic IP address (IPv4). See [Public IPv4 addresses](https://docs.aws.amazon.com/vpc/latest/userguide/vpc-ip-addressing.html#vpc-public-ipv4-addresses).
* If we want our instance in the public subnet to communicate with the internet over IPv6, it must have an IPv6 address.
* An instance launched into a public subnet has two IPv4 addresses. One is a private IPv4 address and the other one is public IPv4 address.
* When we communicate with a resource within a VPC, the resource sees that traffic is coming from the private IPv4 address.
* But when we communicate with the internet, the resources see that traffic is coming from the public IPv4 address. Here, [Network address translation](https://en.wikipedia.org/wiki/Network_address_translation) (NAT) takes place.
* The instance can be accessed through the public IPv4 address or Elastic IP address which is attached to the instance.

#### Internet Gateway

> An internet gateway is a horizontally scaled, redundant, and highly available VPC component that allows communication between your VPC and the internet.
>
> An internet gateway serves two purposes: to provide a target in your VPC route tables for internet-routable traffic, and to perform network address translation (NAT) for instances that have been assigned public IPv4 addresses.
>
> An internet gateway supports IPv4 and IPv6 traffic. It does not cause availability risks or bandwidth constraints on your network traffic.

### Private Subnet

> If a subnet doesn't have a route to the internet gateway, the subnet is known as a _private subnet_.

A private subnet is a network to which no internet gateway is attached. So, we won't be able to communicate with the internet from an instance launched in a private subnet. But here is a catch.

NAT Gateway or Instance is attached to a private subnet so that any resource within the subnet can access the internet. We can use a single NAT Gateway or Instance for a single private subnet or for multiple private subnets within the VPC.

From our previous example, we can attach two NAT gateways to **Subnet-2** and **Subnet-4**. Then these subnets will be considered as private subnets. It is recommended to create subnets in multiple availability zones. So, we may create **Subnet-2** in Zone-A and **Subnet-4** in Zone-B.

Points to be noted:

* We need not attach public IPv4 address to an instance in a private subnet to access the internet.
* When we communicate with a resource within a VPC, the resource sees that traffic is coming from the private IPv4 address.
* But when we communicate with the internet, the resources see that traffic is coming from the public IPv4 address of NAT Gateway or NAT Instance.
* All resources within a private subnet, attached to a NAT Gateway/Instance, share the same public IPv4 address of that NAT Gateway/Instance while communicating with the internet.
* The instance can't be accessible through the public IPv4 address of NAT Gateway/Instance which is attached to its subnet.
* We should assign larger CIDR blocks in private subnets than public subnets. Normally, we require to launch more resources in private subnet rather than public subnet.

#### NAT Gateway

> You can use a network address translation (NAT) gateway to enable instances in a private subnet to connect to the internet or other AWS services, but prevent the internet from initiating a connection with those instances. For more information about NAT, please see [NAT](https://docs.aws.amazon.com/vpc/latest/userguide/vpc-nat.html).

![NAT Gateway](https://docs.aws.amazon.com/vpc/latest/userguide/images/nat-gateway-diagram.png)

Points to be noted:

* A NAT gateway automatically reserves and uses an IPv4 address from the public subnet of the same VPC for which private subnet's we are creating NAT gateway.
* The NAT gateway automatically provisions an Elastic IP address for itself.

#### NAT Instance

> You can use a network address translation (NAT) instance in a public subnet in your VPC to enable instances in the private subnet to initiate outbound IPv4 traffic to the internet or other AWS services, but prevent the instances from receiving inbound traffic initiated by someone on the internet.

![NAT Instance](https://docs.aws.amazon.com/vpc/latest/userguide/images/nat-instance-diagram.png)

Points to be noted:

* A NAT instance has to be launched in a public subnet of the same VPC for which private subnet's we are creating NAT instance.
* The NAT instance must have an Elastic IP address.

### Intra Subnet

It's a bit of community-made idea, rather than AWS'. An intra or protected subnet is a private subnet to which no NAT Gateway/Instance is attached. This means, it is completely isolated from the internet and no one can reach in/out to the instance of intra subnet.

## Route Table

> A _route table_ contains a set of rules, called _routes_, that are used to determine where network traffic from your subnet or gateway is directed.

A route table is like a tour guide for network traffic. When we send traffic from any AWS resource within our VPC, the traffic follows the route table to reach the destination.

Points to be noted:

* Every route table contains a local route for communication within the VPC. This route is added by default to all route tables.
* If a VPC has more than one IPv4 CIDR block, the route tables contain a local route for each IPv4 CIDR block.
* If a route table has multiple routes, AWS uses the most specific route that matches the traffic (longest prefix match) to determine how to route the traffic.

There are five types of route table on AWS at a high level:

* **Main route table**: Main route table is automatically created when we create a VPC. It controls the routing for all subnets that are not explicitly associated with any other route table.
* **Custom route table**: A route table that we create for your VPC on our own.
* **Subnet route table**: A route table that is associated with a subnet.
* **Gateway route table**: A route table that is associated with a gateway - internet gateway, nat gateway, or virtual private gateway.
* **Local gateway route table**: A route table that is associated with an Outposts local gateway. For information about local gateways, see [Local Gateways](https://docs.aws.amazon.com/outposts/latest/userguide/outposts-local-gateways.html) in the AWS Outposts User Guide.

### Route

> Each route in a table specifies a destination and a target.

A route has two major components:

* **Destination**: A CIDR block where we want traffic to go (destination CIDR).
* **Target**: The gateway, network interface, or connection through which to send the destination traffic.

Example:

| Destination | Target |
| :---: | :---: |
| 0.0.0.0/0 | igw-1234567890 |

The destination for the route is `0.0.0.0/0`, which represents all IPv4 addresses. The target is the internet gateway that's attached to our VPC.

Sometimes, we will see the route as follows:

| Destination | Target |
| :---: | :---: |
| 10.0.0.0/16 | local |

This is called **local route**. It is a default route for communication within the VPC.

## VPC Peering

> A VPC peering connection is a networking connection between two VPCs that enables you to route traffic between them privately. Instances in either VPC can communicate with each other as if they are within the same network. You can create a VPC peering connection between your own VPCs, with a VPC in another AWS account, or with a VPC in a different AWS Region.
>
> AWS uses the existing infrastructure of a VPC to create a VPC peering connection; it is neither a gateway nor a VPN connection, and does not rely on a separate piece of physical hardware. There is no single point of failure for communication or a bandwidth bottleneck.

We have already known that resources from one VPC can't reach out to other resources of different VPC. Here comes VPC Peering. It's a network connection between two VPCs.

From the previous example, we already have a VPC `10.0.0.0/16`. Let's call it VPC-A. Then let's assume we have another VPC-B with `172.31.0.0/16` CIDR block. Then we can create a VPC Peering so that they can communicate with each other.

![AWS VPC Peering](https://docs.aws.amazon.com/vpc/latest/peering/images/peering-intro-diagram.png)

But only creating VPC peering won't make them able to communicate with each other. We have to create necessary route entries in related route tables.

An example of a route table for VPC-A:

| Destination | Target |
| :---: | :---: |
| 10.0.0.0/16 | local |
| 172.31.0.0/16 | pcx-1a2b3c4d |

An example of a route table for VPC-B:

| Destination | Target |
| :---: | :---: |
| 172.31.0.0/16 | local |
| 10.0.0.0/16 | pcx-1a2b3c4d |

Points to be noted:

* We cannot create a VPC peering connection between VPCs with matching or overlapping IPv4 CIDR blocks.
* A VPC peering connection is a one to one relationship between two VPCs. If we have **N** numbers of VPC, then we will require `N*(N-1)/2` numbers of VPC Peering to connect each of them with each other.
* We can create multiple VPC peering connections for each VPC that we own, but transitive peering relationships are not supported.
* We do not have any peering relationship with VPCs that our VPC is not directly peered with.

## Transit Gateway

> A _transit gateway_ is a network transit hub that you can use to interconnect your virtual private clouds (VPC) and on-premises networks.

![Transit Gateway](https://docs.aws.amazon.com/vpc/latest/tgw/images/transit-gateway-centralized.png)

A transit gateway is a regional virtual router with which all of the VPCs are connected and all of them can reach out to each other through this router. This eliminates the limitation of VPC peering. If we use a transit gateway for our previous example, the route tables may look like:

For VPC-A:

| Destination | Target |
| :---: | :---: |
| 10.0.0.0/16 | local |
| 172.31.0.0/16 | tgw-12345 |

For VPC-B:

| Destination | Target |
| :---: | :---: |
| 172.31.0.0/16 | local |
| 10.0.0.0/16 | tgw-12345 |

Points to be noted:

* One VPC's CIDR block must not overlap another VPC's.
* Transit gateway automatically comes with a default route table. By default, this route table is the default association route table and the default propagation route table.
* Transit gateway routes IPv4 and IPv6 packets between attachments using transit gateway route tables.
* We can peer two transit gateways and route traffic between them.

### Conclusion

Enough for today. I have taken a lot of words directly from AWS's official documentation and tried to share an overview of AWS VPC with everyone. Long article, I might misinterpret some information. In that case, please don't hesitate to point out. COVID-19 is running crazy, so stay safe.

Reference: [AWS's official documentation](https://docs.aws.amazon.com/vpc/index.html)

> Originally published at https://blog.maateen.me on July 2, 2020.