AWS VPC (Virtual Private Cloud)
Core Concepts
VPC itself - Spans a single AWS region, all AZs within it - You define a CIDR block (e.g. 10.0.0.0/16) — up to 5 CIDRs per VPC - Default VPC exists in every region; don’t use it for production
Subnets - Subdivisions of your VPC CIDR, tied to a single AZ - Public subnet — has a route to an Internet Gateway (IGW) - Private subnet — no direct internet route; outbound via NAT - AWS reserves 5 IPs per subnet (first 4 + last)
Internet Gateway (IGW) - Horizontally scaled, HA gateway for internet traffic - Attach one per VPC; add a route 0.0.0.0/0 → igw-xxx in public subnet route tables
NAT Gateway - Allows private subnet resources to initiate outbound internet traffic - Deployed in a public subnet; private route table points 0.0.0.0/0 → nat-xxx - Managed by AWS (vs. NAT Instance which is self-managed EC2) - One per AZ for HA — NAT GW is AZ-scoped
Routing
- Route Tables — every subnet associates with one; most specific route wins
- Main route table applies to subnets not explicitly associated
- Local route (
10.0.0.0/16 → local) is implicit and can’t be removed
Security
| Security Groups | Network ACLs | |
|---|---|---|
| Level | Instance (ENI) | Subnet |
| State | Stateful | Stateless |
| Rules | Allow only | Allow + Deny |
| Evaluation | All rules | Rule order (lowest #) |
Security Groups are your primary control. NACLs are a coarse backstop — rarely needed.
Connectivity
VPC Peering - Direct private connection between two VPCs (same or cross-account/region) - Non-transitive — A↔︎B, B↔︎C does not mean A↔︎C - No overlapping CIDRs allowed
Transit Gateway (TGW) - Regional hub-and-spoke router; attach VPCs, VPNs, Direct Connect - Replaces complex peering meshes; supports transitive routing - Costs more — worth it at scale (5+ VPCs)
VPC Endpoints - Gateway endpoint — S3 and DynamoDB; free; adds prefix list to route table - Interface endpoint (PrivateLink) — ENI in your subnet for most AWS services; hourly cost - Keeps traffic off the internet entirely
VPN - Site-to-Site VPN — IPsec tunnel to on-prem; uses Virtual Private Gateway (VGW) or TGW - Client VPN — OpenVPN-based for individual users
Direct Connect (DX) - Dedicated physical link to AWS; lower latency, consistent throughput - Not redundant by itself — pair with VPN or second DX for HA
DNS
enableDnsSupport— enables Route 53 Resolver (169.254.169.253)enableDnsHostnames— assigns public DNS names to instances with public IPs- Both must be
truefor VPC endpoints and private hosted zones to work - Route 53 Resolver inbound/outbound endpoints for hybrid DNS
IP Addressing
- IPv4 (required) + optional IPv6 (
/56assigned to VPC,/64to subnets) - Elastic IP (EIP) — static public IPv4; charged when not in use
- BYOIP — bring your own public IP block
Flow Logs
- Capture IP traffic metadata at VPC, subnet, or ENI level
- Publish to CloudWatch Logs, S3, or Kinesis Data Firehose
- Don’t capture payload — metadata only (src/dst IP, port, action, bytes)
- Essential for security analysis and troubleshooting
Design Patterns (for your context)
For a Django/DRF app on AWS ap-southeast-2:
VPC 10.0.0.0/16
├── Public subnets (10.0.0.0/24, 10.0.1.0/24, 10.0.2.0/24) — ALB, NAT GW
└── Private subnets (10.0.10.0/24, 10.0.11.0/24, 10.0.12.0/24) — EC2/ECS, RDS, Redis
- ALB in public subnets → forwards to app in private subnets
- RDS and ElastiCache (Redis) in private subnets only
- One NAT GW per AZ if you care about AZ-failure resilience (cost trade-off: use one NAT GW in dev)
- VPC endpoints for S3 (gateway, free) and ECR/Secrets Manager (interface, saves NAT traffic costs)
- Security groups: ALB → app SG, app SG → RDS SG (no broad CIDR rules)
Common Gotchas
- Forgetting NAT GW is AZ-scoped → single point of failure if only one
- Overlapping CIDRs blocking peering/VPN later — plan CIDR space upfront
- NACLs are stateless — must allow inbound and outbound (including ephemeral ports
1024–65535) - Interface endpoints have per-AZ costs — evaluate vs. NAT GW cost for your traffic volume
- Default VPC’s subnets are all public — never run prod workloads there