Core Implementation: Route Tables and NAT Gateways
Route Table Architecture
The routing layer is where the isolation you designed in subnets becomes operational. At this point, all six subnets are associated with the main route table, which only has a local route. Nothing can reach the internet and nothing can receive traffic from the internet. You will now build three distinct routing tiers.
You need four route tables:
rtb-public— routes0.0.0.0/0to the IGW; associated with both public subnetsrtb-private-app-az1— routes0.0.0.0/0to NAT-AZ1; associated withprivate-app-az1rtb-private-app-az2— routes0.0.0.0/0to NAT-AZ2; associated withprivate-app-az2rtb-private-db— no default route; associated with both DB subnets
The DB subnets intentionally have no route to the internet. Database instances should never initiate or receive internet connections. If your database needs to pull updates, the recommended pattern is to use a VPC endpoint for AWS services or route through a proxy in the application tier.
Creating NAT Gateways
Navigate to VPC > NAT Gateways > Create NAT Gateway. Create two NAT Gateways, one per AZ.
For each:
- Subnet: select the corresponding public subnet (
public-az1for the first,public-az2for the second) - Connectivity type: Public
- Elastic IP: click “Allocate Elastic IP” to create a new one
Name them nat-az1 and nat-az2.
NAT Gateways take 1–2 minutes to reach “Available” state. Wait before proceeding to the route table step — associating a route with a pending NAT Gateway causes intermittent failures.
What you should see: Both NAT Gateways in “Available” state, each with an Elastic IP and placed in the correct public subnet.
Why public subnets for NAT Gateways? A NAT Gateway must itself have a path to the internet to forward traffic on behalf of private instances. Placing it in a public subnet (which has the IGW route) satisfies this requirement. Placing a NAT Gateway in a private subnet is a configuration error that results in an “Available” gateway that drops all outbound traffic silently.
Creating and Associating Route Tables
Navigate to VPC > Route Tables > Create route table.
Public route table (rtb-public):
- After creation, go to Routes > Edit routes > Add route
- Destination:
0.0.0.0/0, Target: select Internet Gateway →lab-igw - Go to Subnet associations > Edit subnet associations
- Associate
public-az1andpublic-az2
Private app route tables:
- Create
rtb-private-app-az1, add route0.0.0.0/0→nat-az1, associateprivate-app-az1 - Create
rtb-private-app-az2, add route0.0.0.0/0→nat-az2, associateprivate-app-az2
Database route table (rtb-private-db):
- Create
rtb-private-db, add no additional routes beyond the local route - Associate
private-db-az1andprivate-db-az2
What you should see: Each route table shows the correct number of associated subnets. The public route table shows two routes (local + IGW). The app route tables each show two routes (local + NAT). The DB route table shows one route (local only).
Validating connectivity intent: At this point, launch a test EC2 instance (Amazon Linux 2, t3.micro) in private-app-az1 with no public IP. Use EC2 Instance Connect or SSM Session Manager to access it. Run:
curl -s --max-time 5 https://example.comYou should receive an HTTP response. If the command times out, your route table association is incorrect or the NAT Gateway is not yet in Available state.
Common misconfiguration: Associating the wrong AZ’s private subnet with the wrong AZ’s NAT Gateway route table. This means cross-AZ NAT traffic, which works but defeats the HA design and incurs cross-AZ data transfer charges.

In this section, I confirmed:
0 of 5 completed
Route Table Validation
Question 1 of 2
A private EC2 instance sends a request to 8.8.8.8. What is the correct traffic path?