Hi reader! This is part of a series on AWS Networking. The story so far: we've learned about VPCs. We've learned about subnets. We created a subnet and an internet gateway. Now we want to connect our subnet to the internet gateway. In order to do that, we need to learn about CIDR notation and route tables. This chapter is on route tables (“root tables”?).
tl;dr
Make a new route table
Add a rule to route to your internet gateway
Associate this route table with a subnet
Longer explanation:
Here comes a packet
Someone wants to connect to your server. A packet comes in, with a destination IP address, and says "help I'm trying to go to 175.88.11.12". How do we know where the packet needs to go?
Another packet comes up and says "help I'm trying to get to 142.250.191.110". This packet actually wants to go out to the internet. How do we direct this packet?
The answer to both questions is a route table! A route table will map a destination to a target.
Route tables are mappings from a destination to a target
Route tables are set up so given a destination, the route table tells you the next step to take. It's just like if you're trying to go to a city:
In this example, the route table would look like this
The destination you're trying to get to is Mumbai, and the next step you need to go to is the airport.
Nuance! The route table doesn't tell the packet how to get to its final destination. It just tells the packet the NEXT STEP to take.
We want to connect a subnet to an internet gateway. The route table for that might look like this:
Lets break down what this table is saying.
Local or internet?
Suppose a packet comes in with a destination IP address. That IP address can be within your VPC, in which case the route table should route it locally
The route table tells the packet where to go next. If it's any other IP address, it should route it to your internet gateway
What does the route table for the logic above look like? Well, to start we need two routes:
If our EC2 instance wants to hit an IP address inside our VPC, we route that request locally inside the VPC
if it wants to hit any other IP address, we route that request to the internet, through the internet gateway
Here's what the route table for the logic above would look like:
You’ll notice we are using CIDR notation to specify a range of IP addresses (quick tutorial on CIDR here). The first rule says, any IP address that starts with 175.88
should get routed locally. The second rule says, all IP addresses should get routed to the internet gateway.
You can add routes for specific IP addresses,
but typically you will create routes for CIDR ranges.
Route tables pick the most specific route that matches
The route table in our example had two routes
Notice that one of the routes matches any IP address
while the other one matches only IP addresses in your VPC
So if a packet comes in with a local IP address, technically it matches both routes. Where will it go? Route tables will always try to match the most specific route.
Psst… how is the matching done? Using something called a Genmask. This isn't need-to-know information, so I won't describe it here, but now you know the word and can look it up if you want to.
The main route table
Route tables are created at the VPC level.
This means VPCs can have many route tables. Every VPC comes with a route table, called the main route table. This route table will have a route by default that maps your VPC's CIDR range to the local
target. Typically, you want to leave this as is.
Subnets and route tables
All subnets are associated with the main route table by default. Suppose you have two subnets, both private. You're trying to make one of them public, i.e. giving it a connection to the internet. You do this by attaching it to an internet gateway. To do that, you need to add a route to your route table. Suppose you add a route like this to your main route table:
This works, and one of your subnets is now public. Unfortunately, all of your subnets are now public! Since you made this change on the main route table, and all subnets are associated with the main route table by default, all your subnets are now public.
To make a subnet public, you instead want to make a new route table and associate your subnet with that route table.
But there's a gotcha here. Subnets can only be associated with one route table at a time, so now your subnet will no longer be associated with the main route table. Remember that the main route table had that route for local traffic. Now your public subnet can no longer handle local traffic! If you want the subnet to handle local traffic, you'll have to add a route to your new route table to handle local traffic.
Terraform
# Make a route table with one route,
# which matches any IP address and
# sends it to the internet gateway.
resource "aws_route_table" "public" {
vpc_id = aws_vpc.main.id
route {
cidr_block = "0.0.0.0/0"
gateway_id = aws_internet_gateway.igw.id
}
}
# Associate the route table with the subnet.
resource "aws_route_table_association" "public_subnet_asso" {
subnet_id = aws_subnet.public.id
route_table_id = aws_route_table.public.id
}
(Excuse the lack of syntax highlighting — Substack doesn’t have that)
Here is the Terraform code for everything we have learned so far, including making a VPC, subnet, etc: Github gist
Bonus command line tip!
If you are SSHed into an EC2 instance, you can see the route table by using the route
command. You can also do netstat -r
, which just calls route -e
in the background.
Summary
Phew! You finally have a route in place, and your subnet is connected to the internet gateway. Here's what we have so far:
Bullet points
To connect a subnet to the internet, you need a route.
Routes are defined as rules in a route table.
A route table matches a destination to a target.
Destinations are usually specified as CIDR ranges.
Route tables are created on the VPC level. Each VPC comes with a default route table called the main route table.
You probably want to create a new route table and associate it with a subnet. Subnets can only be associated with one route table at a time.
Your subnet is now connected to the internet, but you still need to set up your security rules to allow traffic in. We’ll see that next!