VPC & Networking
A Virtual Private Cloud (VPC) is your own logically isolated, software-defined network inside AWS. You control its IP address range, how it’s carved into subnets, how traffic is routed, and how it connects to the internet and to other networks. Every EC2 instance, RDS database, and most managed services live inside a VPC, so understanding it is essential for building secure, well-architected systems.
CIDR blocks
When you create a VPC you assign it a private CIDR block - a range of IP addresses in address/prefix notation. For example, 10.0.0.0/16 provides 65,536 addresses (10.0.0.0-10.0.255.255). The smaller the prefix number, the larger the range.
Choose a CIDR from the RFC 1918 private ranges (
10.0.0.0/8,172.16.0.0/12,192.168.0.0/16) and avoid overlapping with networks you may later peer with or connect over VPN. Overlapping CIDRs are painful to fix after the fact - plan generously up front.
Subnets
Subnets divide the VPC CIDR into smaller ranges, each bound to a single Availability Zone. The public/private distinction is about routing, not a checkbox:
- Public subnet — its route table sends
0.0.0.0/0to an Internet Gateway. Resources here can have public IPs and be reachable from the internet (e.g. load balancers, bastion hosts). - Private subnet — no direct route to the internet. Resources here (app servers, databases) are reachable only from within the VPC, and reach out via a NAT gateway.
AWS reserves the first four and the last IP address in every subnet, so a
/24(256 addresses) yields 251 usable IPs. Account for this when sizing.
Route tables
A route table is a set of rules that decides where network traffic is directed. Each subnet associates with exactly one route table. The “public vs private” nature of a subnet is determined entirely by its route table’s default route.
| Destination | Target | Meaning |
|---|---|---|
10.0.0.0/16 | local | Intra-VPC traffic (always present) |
0.0.0.0/0 | igw-xxxx | Public subnet → internet |
0.0.0.0/0 | nat-xxxx | Private subnet → outbound internet via NAT |
Internet Gateway vs NAT Gateway
These are often confused but serve opposite directions of traffic.
- Internet Gateway (IGW) — a horizontally scaled, highly available component that allows bidirectional communication between the VPC and the internet. One per VPC.
- NAT Gateway — lets resources in private subnets initiate outbound connections (e.g. to download updates or call APIs) while preventing inbound connections from the internet. It lives in a public subnet.
A NAT Gateway has an hourly charge plus a per-GB data-processing fee, and it’s billed even when idle. For high-egress workloads this surprises many teams. Use VPC Gateway/Interface Endpoints to reach S3, DynamoDB, and other AWS services privately and skip NAT costs entirely.
Security Groups vs Network ACLs
Two firewall layers protect your resources, and they behave differently.
| Aspect | Security Group | Network ACL |
|---|---|---|
| Applies to | Instance / ENI | Subnet |
| State | Stateful (return traffic auto-allowed) | Stateless (must allow both directions) |
| Rules | Allow only | Allow and Deny |
| Evaluation | All rules evaluated | Rules in numbered order, first match wins |
| Default | Deny all inbound, allow all outbound | Allow all (default NACL) |
Use security groups as your primary control - they’re stateful and instance-scoped. Reserve NACLs for coarse, subnet-wide guardrails (like blocking a malicious IP range), since their stateless, ordered nature makes them error-prone for fine-grained rules.
A simple architecture
A standard two-AZ web application looks like this:
Internet
|
[ Internet Gateway ]
|
┌───────────────────┴───────────────────┐
| VPC 10.0.0.0/16 |
| |
| AZ-a AZ-b |
| ┌──────────────┐ ┌──────────────┐|
| │ Public subnet│ │ Public subnet││
| │ 10.0.1.0/24 │ │ 10.0.2.0/24 ││
| │ ALB + NATGW │ │ ALB ││
| └──────┬───────┘ └──────┬───────┘|
| │ │ |
| ┌──────┴───────┐ ┌──────┴───────┐|
| │Private subnet│ │Private subnet││
| │ 10.0.11.0/24 │ │ 10.0.12.0/24 ││
| │ App + RDS │ │ App + RDS ││
| └──────────────┘ └──────────────┘|
└────────────────────────────────────────┘
Public subnets hold the load balancer and NAT gateway; private subnets hold application servers and databases, which reach the internet only outbound through NAT and are never directly exposed.
Best Practices
- Span at least two AZs with paired public/private subnets for high availability.
- Keep databases and app tiers in private subnets; expose only load balancers publicly.
- Lean on security groups for fine-grained control; use NACLs sparingly as subnet guardrails.
- Use VPC Endpoints for AWS service traffic to cut NAT cost and keep traffic off the public internet.
- Enable VPC Flow Logs for network visibility and incident investigation.
- Plan non-overlapping CIDRs up front to allow future peering, Transit Gateway, and VPN connectivity.