VPC design patterns
An Amazon Virtual Private Cloud (VPC) is a logically isolated virtual network in an AWS account and Region. You control its IP addressing, subnets, routing, and the gateways or endpoints that connect it to the internet, other VPCs, AWS services, and on-premises networks. Good VPC design is mostly about making traffic paths explicit: which resources are reachable, from where, and through which controls.
Addressing and subnet layout
A subnet is a range of IP addresses in your VPC. Each subnet must reside entirely within one Availability Zone and cannot span zones. AWS recommends placing resources in separate Availability Zones so a single zone failure does not take down the whole application.
Subnet type is determined by routing, not by a label in the console:
- Public subnet: the route table has a direct route to an internet gateway. Resources here can reach the public internet if they also have the addressing and security rules required.
- Private subnet: there is no direct route to an internet gateway. Outbound internet access, when needed, typically goes through a NAT device.
- Isolated subnet: there are no routes to destinations outside the VPC. Resources can communicate only with other resources in the same VPC.
- VPN-only subnet: traffic to remote networks goes through a virtual private gateway for a Site-to-Site VPN connection, with no direct internet gateway route.
When planning subnets, choose IPv4 CIDR ranges that fit current workloads and future growth, and decide whether the VPC or subnet will be IPv4-only, dual stack, or IPv6-only. Dual-stack subnets can carry IPv4 and IPv6 traffic; IPv6-only subnets have no IPv4 CIDR block and require IPv6-capable application paths.
Routing: internet, NAT, and private connectivity
Every subnet is associated with a route table. The route table controls where outbound traffic from that subnet is directed. New subnets are associated with the VPC main route table by default, but production designs usually assign explicit route tables so public and private subnets cannot accidentally share the same paths.
For outbound-only internet access from private subnets, AWS provides NAT gateways. A NAT gateway performs network address translation so instances in a private subnet can connect to services outside the VPC, while external services cannot initiate connections back to those instances.
NAT gateway connectivity type changes the design:
- Public NAT gateway (default): created in a public subnet and associated with an Elastic IP address at creation. The subnet route table sends outbound traffic to the NAT gateway, and the NAT gateway routes to the VPC internet gateway. Public NAT gateways can also be used for paths to other VPCs or on-premises networks through a transit gateway or virtual private gateway.
- Private NAT gateway: not associated with an Elastic IP address. It is used to connect private subnets to other VPCs or on-premises networks through a transit gateway or virtual private gateway. You can attach an internet gateway to the same VPC, but if traffic from a private NAT gateway is routed to that internet gateway, the internet gateway drops it.
Connections through a NAT gateway must be initiated from within the VPC containing the NAT gateway. For outbound-only IPv6, AWS documents egress-only internet gateways as an alternative; IPv4 and IPv6 NAT behavior also has DNS64/NAT64 considerations that should be reviewed when building IPv6-enabled applications.
Security layers: security groups and network ACLs
VPC traffic filtering happens at two common layers.
Security groups act as stateful virtual firewalls for associated resources, such as EC2 instances or network interfaces. You define inbound and outbound rules with protocol, port range, and source or destination. Because security groups are stateful, return traffic for an allowed request is permitted without a matching opposite-direction rule. There is no additional charge for security groups.
Network ACLs (NACLs) operate at the subnet boundary. They are stateless: responses to allowed inbound traffic are not automatically allowed outbound, and vice versa. Rules are evaluated in order starting from the lowest rule number; the first matching rule is applied. Every subnet must be associated with one network ACL. If you do not choose one, the subnet uses the VPC default network ACL, which allows all inbound and outbound traffic. A subnet can be associated with only one NACL at a time, while a NACL can be associated with multiple subnets.
Security groups are usually the primary control because they are attached to workloads and track connection state. NACLs are useful as a coarse subnet guardrail, but overlapping stateless rules make them easy to misconfigure. AWS also notes that security groups and NACLs do not filter some AWS-reserved traffic, such as traffic to the VPC DNS resolver, DHCP, instance metadata, and the default VPC router addresses.
Private access to AWS services
Not every design needs traffic to leave the VPC for AWS service access. With AWS PrivateLink, clients in a VPC can connect to services and resources in other VPCs using private IP addresses, as if those services were hosted locally. Traffic between a VPC endpoint and an endpoint service or resource stays on the AWS network rather than traversing the public internet.
PrivateLink supports several VPC endpoint types, including interface endpoints for TCP or UDP traffic to endpoint services and resource endpoints for direct access to shared resources. Gateway endpoints for Amazon S3 and DynamoDB are a different mechanism and do not use AWS PrivateLink. The right choice depends on the target service, DNS behavior, routing model, and policy requirements.
Operational checks
A VPC that looks correct on a diagram can still fail in practice. Before calling a design ready, verify:
- Route tables match intent for every subnet, especially default routes (
0.0.0.0/0and IPv6 equivalents) and routes to on-premises or peered networks. - NAT capacity and failure domains match availability goals. Public NAT gateways are Availability Zone-scoped resources; multi-AZ architectures need NAT paths designed per zone.
- Security group rules are narrow, and SSH/RDP access is limited to specific address ranges rather than the entire internet.
- NACL rule order and ephemeral-port return traffic are checked anywhere NACLs are used.
- VPC Flow Logs are enabled where network troubleshooting or security review requires traffic metadata.
Conclusion
A solid VPC design makes every network path deliberate. Use subnet boundaries and route tables to separate public entry points from private workloads, choose NAT or endpoint patterns that match the required destination, and apply security groups and NACLs with their stateful or stateless behavior in mind. Treat the result as testable infrastructure: if a packet should not flow, the route, firewall rule, and log signal should make that obvious.
Sources
- Amazon VPC documentation
- What is Amazon VPC?
- Subnets for your VPC
- NAT gateways
- Control traffic to your AWS resources using security groups
- Control subnet traffic with network access control lists
- AWS PrivateLink concepts