Phase 2: Core Cloud Services

Public & private subnets, route tables & NAT gateways

Intermediate ~3 min read
Think of it this way A friendly analogy. Read this if the technical version feels dense. Show Hide

Imagine our whole online project is like building a super cool, big house in a neighborhood. This whole neighborhood is yours to design! Just like in a real neighborhood, you'll want some parts of your house to be easy for visitors to find, like your front porch or a sign out front for a lemonade stand. These are like your public areas. They're perfect for things that need to be seen or accessed directly by anyone on the internet, like the front door of your website or a special computer you use to quickly jump into your project. They have a clear path to the main roads outside your neighborhood.

But then, you have other parts of your house – like your secret club treehouse, your bedroom where your favorite toys live, or your super-secret diary. These are your private areas. You definitely don't want strangers from the internet poking around in here! So, you put all your really important stuff, like your game saves, your best story ideas, or the secret ingredients for your grandma's cookies, in these private spots. This way, you keep everything safe and sound, making sure that only you decide who gets to see or touch what.

Now, how do things get from one part of your house to another, or even to the big wide world outside? That's where route tables come in. Think of route tables as the special maps for each room or area in your house. Every single area has its own map that tells any message or piece of information exactly where to go. For your public front porch, the map clearly shows the way to the main street outside your neighborhood. But for your private treehouse or bedroom, the map doesn't show a direct path to the outside. Instead, if something from your private area needs to send a message out to the internet – like your game console needing to download an update – its map directs it to a special "community post office" in your neighborhood.

This special post office is like a NAT gateway. It’s super smart! If your game console sends a message to the post office asking for an update, the post office takes your message, wraps it in a new, anonymous envelope, and sends it out to the internet on your behalf. When the update comes back, the post office makes sure it gets safely delivered right back to your game console in your private area, without ever letting the outside world know exactly where your private area is. It’s like having a secure messenger service. This means you can build amazing online projects where your public parts are welcoming to everyone, while your most important secrets and data are kept super safe and private, but can still get updates or information from the internet when needed.

A well-designed Virtual Private Cloud (VPC) leverages public and private subnets to create a secure and functional network environment. Public subnets are intended for resources that require direct internet access, such as load balancers, bastion hosts, or public-facing web servers. These subnets achieve internet connectivity via an Internet Gateway (IGW) attached to the VPC. Conversely, private subnets house your sensitive application components like database servers, application servers, or internal microservices, which should never be directly exposed to the internet. This segregation is a cornerstone of secure cloud architecture, allowing you to tightly control external access based on the role of each resource.

Route tables are the traffic directors within your VPC. Every subnet must be associated with a route table, which contains rules that determine where network packets are sent based on their destination IP address. For a public subnet, its route table will typically have a default route (0.0.0.0/0) pointing to the Internet Gateway, enabling direct internet access. However, for a private subnet, direct access to the Internet Gateway is deliberately omitted. Instead, if instances within a private subnet need to initiate outbound connections to the internet (e.g., for software updates, fetching dependencies, or sending logs), their default route will point to a NAT Gateway.

A NAT Gateway (Network Address Translation Gateway) is a crucial component that allows instances in private subnets to securely access the internet for outbound connections while preventing unsolicited inbound connections from the internet. You deploy a NAT Gateway in a public subnet and it is assigned an Elastic IP address. Private subnets are then configured with a route table entry that directs all internet-bound traffic (0.0.0.0/0) to the NAT Gateway. The NAT Gateway performs network address translation, presenting its public IP address to the internet on behalf of the private instances, thereby preserving the isolation and security of your private resources.

Key Takeaways

  • Public subnets provide direct internet access via an Internet Gateway for public-facing resources.
  • Private subnets host sensitive resources, lacking direct internet access for enhanced security.
  • Route tables define traffic flow; public subnets point default traffic to IGW, private subnets point to NAT Gateway for outbound access.
  • NAT Gateways enable instances in private subnets to initiate outbound internet connections securely.
  • A NAT Gateway must be deployed in a public subnet.

Code Example

terraform
resource "aws_route_table" "private_rt" {
  vpc_id = aws_vpc.main.id

  route {
    cidr_block = "0.0.0.0/0"
    nat_gateway_id = aws_nat_gateway.example.id
    # This route directs all outbound internet traffic from associated subnets
    # through the specified NAT Gateway.
  }

  tags = {
    Name = "Private-Subnet-Route-Table"
  }
}

resource "aws_route_table_association" "private_subnet_association" {
  subnet_id      = aws_subnet.app_private_us_east_1a.id
  route_table_id = aws_route_table.private_rt.id
  # This associates the route table with a specific private subnet.
}

How this code works

This code establishes the necessary routing for private subnets to access the internet securely, without exposing their instances directly. Specifically, it configures a route table to direct all outbound internet traffic from private subnets through a NAT Gateway, and then associates this route table with a designated private subnet.

The resource "aws_route_table" "private_rt" block defines a new route table. Inside its route block, the cidr_block = "0.0.0.0/0" signifies all possible internet addresses, meaning any traffic going to the internet will be routed via the nat_gateway_id. This setup allows instances within associated private subnets to initiate connections to services on the internet, such as downloading updates, while remaining protected from unsolicited inbound internet traffic.

The resource "aws_route_table_association" "private_subnet_association" then links this custom route table (private_rt) to a specific private subnet identified by aws_subnet.app_private_us_east_1a.id. This is a crucial step; a subtle point is that without such an explicit aws_route_table_association, subnets in AWS automatically receive a default route table. For private subnets, this default table typically only routes traffic within the VPC, meaning they wouldn't have internet access. This association ensures the private subnet uses the NAT Gateway for all its internet-bound communications.