AWS VPC Networking Explained: Subnets, Route Tables, and NAT

VPC networking is where most cloud engineers' mental models break down. You can deploy applications for years on the default VPC without understanding what a route table does, until the day a Lambda in a private subnet can't reach the internet, or a database is accidentally public. This post builds the mental model from scratch, the way I teach it.

The VPC is just an address space

A VPC is a private slice of IP address space, defined by a CIDR block like 10.0.0.0/16: about 65,000 addresses that belong to you. Nothing in it can be reached from outside until you explicitly create a path. Every piece of VPC networking is about controlling those paths.

Subnets: public is a configuration, not a type

A subnet is a smaller CIDR range inside the VPC, tied to one Availability Zone. Here's the part that unlocks everything: there is no "public subnet" checkbox. A subnet is public only because its route table sends 0.0.0.0/0 to an Internet Gateway. A private subnet is just one whose route table doesn't. The subnet itself is identical; the route table defines its nature.

Route tables: the actual decision-makers

Every subnet consults exactly one route table to decide where traffic goes. A typical pair looks like this:

When something "can't connect", the route table is the first place I look, before security groups, before DNS.

Internet Gateway vs NAT Gateway

The Internet Gateway is a two-way door: traffic in and out, for resources with public IPs. The NAT Gateway is a one-way door: instances in private subnets can initiate outbound connections (pulling packages, calling external APIs), but inbound connections are impossible. Two practical notes that bite people: a NAT Gateway must itself live in a public subnet, and it costs money per hour and per GB. An idle NAT Gateway in three AZs is a surprisingly common line item on the bill.

Security groups vs NACLs

The three-tier layout I use by default

For production workloads, my starting template across two AZs:

Once you internalise that subnets are defined by their route tables and that security group references (not IP ranges) should chain your tiers together, VPC design stops being mysterious. Draw the route tables first; everything else follows.

Frequently asked questions

What makes a subnet public in AWS?

Only its route table. A subnet is public when its route table sends 0.0.0.0/0 to an Internet Gateway; a private subnet is one whose route table doesn't. There is no 'public subnet' setting on the subnet itself.

What is the difference between an Internet Gateway and a NAT Gateway?

An Internet Gateway is a two-way door: traffic in and out for resources with public IPs. A NAT Gateway is one-way: instances in private subnets can initiate outbound connections, but nothing can connect in. A NAT Gateway must live in a public subnet and is billed per hour and per gigabyte.

Security groups vs NACLs: which should I use?

Security groups for almost everything. They are stateful, instance-level, allow-only firewalls and should carry about 95% of your access control. NACLs are stateless subnet-boundary filters that support deny rules; leave them at defaults unless you need a hard subnet-level block.

← All posts