What actually makes a subnet public or private in AWS?
Show the answer
Say this first
Only its route table. A public subnet is associated with a route table that has a default route
(0.0.0.0/0) to an internet gateway. A private subnet has no route to an internet gateway; it
usually sends 0.0.0.0/0 to a NAT gateway instead. The instance also needs a public IP to be
reachable from the internet.
Go deeper
The three conditions for an instance to talk to the internet directly
- Its subnet's route table has
0.0.0.0/0(or::/0) pointing to anigw-target. - It has a public IPv4 address or an Elastic IP (or a global IPv6 address).
- Security group and network ACL allow the traffic.
Miss any one and it does not work. "Public subnet" is not a checkbox; it is a label people use for condition 1. The "auto-assign public IPv4" subnet setting only helps with condition 2.
Typical route tables
rtb-public rtb-private-a
10.10.0.0/16 local 10.10.0.0/16 local
0.0.0.0/0 igw-0c1d2e3f4a5b60789 0.0.0.0/0 nat-0f1e2d3c4b5a69788Why private subnets
Databases and app servers should not be reachable from the internet at all. In a private subnet they can still start outbound connections (updates, APIs) through the NAT gateway, but nothing can open a connection to them from outside.
They will ask next
An instance has a public IP but sits in a private subnet. Can you reach it?
No. Return traffic would follow the subnet's default route to the NAT gateway, not the internet gateway, and inbound packets to the public IP cannot be delivered without an IGW route. The public IP is useless there.
Where do you put a load balancer for a private web tier?
An internet-facing ALB or NLB goes in public subnets (one per AZ); its targets stay in private subnets. The load balancer nodes have public addresses, the servers do not.
Traps
- Saying a subnet is public because instances in it got public IPs.
- Forgetting that the route table association decides it, and a subnet with no explicit association uses the main route table.