The VPC Context: Public vs Private Subnets

~10 min read

Why a subnet being 'public' or 'private' is a routing decision, not a naming convention.

A subnet's 'public' or 'private' designation isn't a special AWS setting — it's purely determined by its route table. A subnet is public if its route table has a route sending 0.0.0.0/0 (all internet-bound traffic) to an Internet Gateway (a VPC component providing direct two-way internet connectivity). A subnet is private if it has no such route — instances there simply cannot reach the internet directly, and the internet cannot reach them directly, regardless of what Security Group rules say, because the traffic has no path to travel at the network layer at all.

Instances in a private subnet that still need outbound internet access (e.g. to download OS updates or call an external API) route through a NAT Gateway, which lives in a public subnet, has its own Elastic IP, and allows outbound-initiated traffic from the private subnet while still blocking any inbound-initiated connection from the internet — the private instance can call out, but nothing outside can call in.

This is why the standard production pattern places load balancers and NAT Gateways in public subnets, and application servers plus databases in private subnets: even a completely permissive Security Group on a private-subnet instance still can't be reached directly from the internet, because there's no route for that traffic to arrive by. Defense in depth means a mistake at one layer (an overly broad Security Group rule) doesn't automatically become an exposure, because the routing layer independently blocks it too.

In the AWS Console

  1. 1

    VPC → NAT Gateways → Create NAT gateway

    Create it inside a public subnet, allocate an Elastic IP for it, then update the private subnet's route table to send 0.0.0.0/0 traffic to this NAT Gateway.

    A NAT Gateway has an hourly cost plus data processing charges — for a single low-traffic private subnet in a dev environment, this cost is a common surprise for beginners.

💬 Deep Dive with AI

Key points

  • Public vs private subnet is determined by the route table, not a label — public has a route to an Internet Gateway
  • Private subnets can't be reached from the internet regardless of Security Group rules, because there's no network path
  • A NAT Gateway (in a public subnet) lets private-subnet instances make outbound calls without accepting inbound ones
  • Standard pattern: load balancers/NAT Gateways in public subnets, app servers and databases in private subnets