Skip to content

Keep application instances in private subnets

A public subnet is one whose route table has a route to an internet gateway. Placing an instance there gives it a routable public address and puts it one security-group rule away from the open internet. For most workloads there is no reason to accept that exposure.

Web servers, application servers, databases, payment and order processing, inventory and anything else that holds or handles data should sit in private subnets. Inbound traffic reaches them through a load balancer in the public subnets; outbound traffic leaves through a NAT gateway or, better, does not leave the AWS network at all because the destination is reachable through a VPC endpoint.

The resulting shape is:

  • Application Load Balancer (or Network Load Balancer) in the public subnets, one per Availability Zone.
  • Application and data tiers in private subnets across the same Availability Zones.
  • A NAT gateway per Availability Zone for outbound internet access, with each private subnet’s route table pointing at the gateway in its own zone.
  • VPC endpoints for AWS service traffic, so calls to S3, DynamoDB, Secrets Manager and the rest never traverse the internet.

The remaining reasons to use a public subnet

Section titled “The remaining reasons to use a public subnet”

Bastion hosts. A hardened jump box is a legitimate public-subnet resident, though Systems Manager Session Manager removes the need for one in most estates — it gives shell access to private instances without an inbound rule, a public address or an SSH key.

NAT instances. Self-managed NAT instances predate the managed NAT gateway and are now a legacy pattern. Use the NAT gateway unless you have a specific requirement the managed service cannot meet.

Public-facing static content. Serving static files from an EC2 instance in a public subnet is the wrong tool. Put the objects in S3 and front them with CloudFront; send dynamic requests to an ALB.

Private placement is also what makes the rest of the controls tractable. Security groups become tier-to-tier rules rather than internet-facing rules; flow logs describe a small, known set of egress paths; and an accidental permissive rule cannot become an internet-reachable one, because there is no route to an internet gateway to exploit.