Ravindra BagaleCourses & study guides Track your progress

Guides

Public vs Private Subnet in AWS: What Is the Difference?

In AWS, a public subnet is a subnet whose route table has a route 0.0.0.0/0 → internet gateway (igw-…); instances there with a public IP can be reached from the internet. A private subnet has no route to an internet gateway; for outbound internet (updates) its route table sends 0.0.0.0/0 → NAT gateway. The name you type does not matter — only the route table decides.

Come on, friends! In a society some wings face the main road – shops, visitors come there. Some wings are inside – outsiders don't reach them directly. In AWS these are public and private subnets. But note: the name doesn't decide whether a wing is public or private; the direction written on the notice board – that is, the route table – decides.

Quick answer

public-rt  (associated with web-public-1a)      private-rt (associated with app-private-1a)
Destination     Target                           Destination     Target
10.0.0.0/16     local                            10.0.0.0/16     local
0.0.0.0/0       igw-0abc…  (internet gateway)    0.0.0.0/0       nat-0def…  (NAT gateway, optional)

Check which route table a subnet really uses with the AWS CLI:

aws ec2 describe-route-tables --filters Name=association.subnet-id,Values=subnet-0123456789abcdef0 \
  --query "RouteTables[].Routes[].[DestinationCidrBlock,GatewayId,NatGatewayId]" --output table

Empty result? The subnet has no explicit association and uses the VPC's main route table.

What do I need to understand first?

  • A VPC with at least two subnets and an internet gateway attached. If you do not have one yet: How to create a custom VPC in AWS.
  • Every subnet is associated with exactly one route table (explicitly, or implicitly with the main route table). One route table can serve many subnets.
  • Every route table has the local route for the VPC CIDR, so all subnets of a VPC can talk to each other (security groups and network ACLs still apply).

How is traffic routed from a public and a private subnet?

Public route table vs private route table The web server in the public subnet follows public-rt: 0.0.0.0/0 goes to the internet gateway, so it reaches the internet directly. The app server in the private subnet follows private-rt: 0.0.0.0/0 goes to the NAT gateway in the public subnet, which then uses the internet gateway. Both tables also have the local route 10.0.0.0/16 for traffic inside the VPC. Public subnet 10.0.1.0/24 public-rt 10.0.0.0/16 → local 0.0.0.0/0 → igw-… Web server NAT gateway Private subnet 10.0.2.0/24 private-rt 10.0.0.0/16 → local 0.0.0.0/0 → nat-… App server IGW Internet web app

The web server follows public-rt: 0.0.0.0/0 goes to the internet gateway. The app server follows private-rt: 0.0.0.0/0 goes to the NAT gateway in the public subnet. Both tables keep the local route for traffic inside the VPC.

Public subnet Private subnet
Route for 0.0.0.0/0 Internet gateway (igw-…) NAT gateway (nat-…) or none
Reachable from the internet Yes, if the instance has a public IP and the security group allows it No
Can start connections to the internet Yes (needs a public IP) Only through a NAT gateway
Typical servers Load balancer, Nginx web server, bastion host, NAT gateway App servers, databases, internal services

How do I make a subnet public or private?

Step 1 — Make a subnet public

  1. VPC → Route tables → select public-rt → Routes → Edit routes → Add route → 0.0.0.0/0 → Internet Gateway → your IGW → Save.
  2. Subnet associations → Edit subnet associations → tick the subnet → Save.
  3. Subnets → select the subnet → Actions → Edit subnet settings → Enable auto-assign public IPv4 address (otherwise instances get no public IP and are still unreachable).

Step 2 — Make a subnet private

  1. Create private-rt (it starts with only the local route) and associate the private subnets with it.
  2. Do not enable auto-assign public IPv4 there.
  3. For outbound updates, add 0.0.0.0/0 → NAT Gateway later: NAT gateway for a private subnet.

Step 3 — Verify

  • Open the subnet → Route table tab: you should see the 0.0.0.0/0 target you expect.
  • From a public instance: curl -s https://checkip.amazonaws.com prints the instance's public IP.
  • From a private instance (through a bastion): the same command prints the NAT gateway's Elastic IP, or times out if there is no NAT. 🔀

Ravindra Bagale's Tip

Naming a subnet public-subnet doesn't make it public! In class I always ask: "Is there an IGW in the route table?" If not, it is private, however nice the name. The reverse is dangerous too: if you add an IGW route to a private subnet's route table by mistake, the database has moved close to the internet. Always check the Route table tab.

How do I fix public/private subnet problems?

Ghabru naka 😅 — these are the usual ones:

Symptom Likely cause Fix
Instance in "public" subnet times out No 0.​0.​0.​0/​0 → igw-… route, or subnet associated with the main table Add the route; associate the subnet with public-rt
Public subnet, but no public IP on the instance Auto-assign public IPv4 disabled Enable it, or associate an Elastic IP
Private instance: yum hangs, Curl error (28): Timeout was reached No NAT route, or NAT gateway not Available Add 0.​0.​0.​0/​0 → nat-… in private-rt
Route shows Blackhole The NAT gateway or IGW it pointed to was deleted Edit the route to a working target or remove it
New subnets are unexpectedly public The main route table has an IGW route Keep the main table private; use a separate public-rt

Try it at home

Launch one instance in each subnet. From the public one run curl -s https://checkip.amazonaws.com. Then move the private subnet's association to public-rt for two minutes and see what changes — and move it back. Explain the difference in one sentence to a friend.

Got it? A public subnet means 0.0.0.0/0 → IGW in the route table. A private subnet means no IGW, and a NAT gateway if needed. Don't look at the name, look at the route table.

Frequently asked questions

What makes a subnet public in AWS?

Its route table has a route 0.0.0.0/0 to an internet gateway. Instances also need a public IP (auto-assign or Elastic IP) to be reachable from the internet.

What is a private subnet?

A subnet whose route table has no route to an internet gateway. Instances there cannot be reached from the internet; for outbound access they use a NAT gateway.

Does the subnet name decide if it is public?

No. The name is only a tag. AWS decides by the route table associated with the subnet.

Can a private subnet access the internet?

Only outbound, through a NAT gateway in a public subnet: the private route table sends 0.0.0.0/0 to the NAT gateway. Inbound connections from the internet remain impossible.

What is the main route table?

The route table every VPC gets automatically. Subnets without an explicit association use it, so keep it private and create a separate public route table.

What does the local route do?

The local route (the VPC CIDR) is in every route table and lets all subnets of the VPC talk to each other. It cannot be removed.