What makes a subnet "public"
Nothing about the subnet itself. The difference is one row in its route table, the subnet's list of "to reach X, send traffic to Y":
- A public subnet has a route to the internet gateway, the VPC component that passes traffic between your network and the public internet. Instances there can get public IPs and be reached from outside (if their security group allows it, lesson 3-3).
- A private subnet has no such route. Its machines simply cannot be addressed from the internet, no matter what any security group says.
Databases and internal services belong in private subnets: a whole class of attacks disappears when there is no path. When private machines need outbound internet, to fetch OS updates for example, you add a NAT gateway (NAT = network address translation) in a public subnet: it forwards outbound connections under its own public address and lets only the replies back in, so private machines can start conversations with the internet while the internet can never start one with them. (It costs about $32/month, remember it for unit 8.)
The load balancer
One web server means one machine's capacity and one AZ's risk. The standard fix: run two or more identical servers and put an Application Load Balancer (ALB) in front. The ALB is a managed service that owns the public address, accepts every request, and forwards each one to a healthy server, spreading the load.
You have met this shape in deployment work: several containers behind one reverse proxy like nginx. An ALB is that proxy as a rented service, spanning multiple AZs, with health checks built in: it pings each server every few seconds and stops routing to any that fail.
This is the piece that makes the multi-AZ promise from lesson 1-2 real: web servers in 1a and 1b, the ALB in front, and one AZ's outage just means the other keeps serving.
A bad database rule in a private subnet
A security group on a private-subnet database that allows 5432 from 0.0.0.0/0 is contained, because the private subnet has no route from the internet, so there is no path for outside traffic regardless of the rule. The rule should still be fixed.
This is defense in depth. Subnets control whether a path exists at all, and security groups filter what flows along a path that does exist. The two layers are independent, so both have to fail before data is exposed.
The bad rule is genuinely a bug, and leaving it there is unwise for a reason beyond tidiness: the rule quietly grants access to anything that does reach the subnet, including a compromised instance elsewhere in the VPC. It also becomes an internet-facing hole the moment someone adds a route or moves the database to a public subnet.
The right response is to scope the source to the app servers' security group, so the rule states the actual intent rather than relying on the subnet to save it.
Which tier belongs in a private subnet
The database is the part that belongs in a private subnet with no compromise possible.
Only the ALB must be publicly reachable, because it owns the address the internet connects to. Everything behind it can be private.
The app servers can also sit in private subnets, since the ALB reaches them from inside the VPC rather than over the internet. That is the recommended layout, though it is a judgement call that depends on how much you need direct access for debugging.
The database is the one with no argument on the other side. Its only clients are the app servers, which live inside the VPC, so there is nothing that a public route would enable except an attack surface. This exact three-tier layout is lesson 9-2's reference architecture.