Production-ready AWS VPC layout with public, private, and isolated subnets duplicated across two Availability Zones for HA, with NAT gateways for outbound private traffic.
flowchart TB
INET((Internet))
IGW[Internet Gateway]
NAT1[NAT Gateway AZ-A]
NAT2[NAT Gateway AZ-B]
subgraph VPC[VPC 10.0.0.0/16]
subgraph AZA[Availability Zone A]
PUBA[Public Subnet 10.0.0.0/24]
PRIA[Private Subnet 10.0.10.0/24]
DBA[Isolated Subnet 10.0.20.0/24]
end
subgraph AZB[Availability Zone B]
PUBB[Public Subnet 10.0.1.0/24]
PRIB[Private Subnet 10.0.11.0/24]
DBB[Isolated Subnet 10.0.21.0/24]
end
end
INET --> IGW
IGW --> PUBA
IGW --> PUBB
PUBA --> NAT1
PUBB --> NAT2
PRIA --> NAT1
PRIB --> NAT2
PRIA -.-> DBA
PRIB -.-> DBB
DBA -.-> DBB
A multi-AZ VPC topology that AWS recommends for any workload that needs to survive a single-zone outage. Each AZ gets three subnets: a public subnet for load balancers and bastion hosts, a private subnet for application servers (no public IPs, outbound via NAT), and an isolated subnet for databases (no NAT route — only reachable from private subnets). The Internet Gateway handles inbound public traffic; NAT Gateways handle outbound private traffic. Database subnets in different AZs are linked for replication.
Use this layout for any AWS workload that needs four-nines availability or stores regulated data. The three-tier subnet split is the right default for compliance audits — it gives auditors a clear story about which workloads can talk to the internet and which cannot. It is also the layout most Terraform and CDK modules assume, so picking it makes future automation easier.
If cost is a concern, you can run a single shared NAT Gateway across both AZs (cheaper but loses HA on outbound traffic — a single-zone failure breaks egress for the whole VPC). For latency-sensitive apps, add a third AZ with the same three-subnet split. If you do not need a dedicated isolated tier, merge the database into the private subnet and rely on security groups for isolation. For VPC peering or AWS Transit Gateway, leave room in the CIDR by allocating /20 subnets instead of /24.