Amazon VPC (Virtual Private Cloud)
Amazon VPC is the network layer of AWS — a logically isolated section of the AWS cloud where you launch resources into subnets of your own IP ranges. Every EC2, RDS, Lambda-VPC, EKS node, and most other services live in a VPC, making it the foundation of AWS network security and connectivity.
Core Building Blocks:
- VPC: Regional, with an IPv4 CIDR (e.g.,
10.0.0.0/16) and optional IPv6 block.
- Subnet: An AZ-scoped slice of the VPC CIDR. Public subnets route to an Internet Gateway; private subnets don't.
- Internet Gateway (IGW): Horizontally-scaled, stateless device that enables internet access for resources with public IPs.
- NAT Gateway: Managed, AZ-local egress-only NAT for private subnets to reach the internet for patches, API calls, etc.
- Route Tables: Per-subnet rules that decide where traffic leaves the subnet — the IGW, a NAT, a VPN, a Transit Gateway, or a VPC peering.
- Security Groups: Stateful, instance-level firewalls. Allow-only rules by default deny everything.
- Network ACLs (NACLs): Stateless, subnet-level firewalls — use sparingly, usually as a broad-stroke deny layer.
- VPC Endpoints: Private connectivity to AWS services (Gateway endpoints for S3/DynamoDB, Interface endpoints via PrivateLink for everything else) so traffic stays off the public internet.
Connecting VPCs and On-Premises:
- VPC Peering: 1:1 private connection between two VPCs; non-transitive.
- Transit Gateway: Hub-and-spoke router connecting many VPCs, Direct Connect, and VPN in a single region — the standard for multi-VPC architectures.
- Site-to-Site VPN: IPsec tunnel to on-premises equipment over the internet.
- Direct Connect: Dedicated physical circuit (1/10/100 Gbps) to an AWS region for predictable throughput and lower cost at scale.
- PrivateLink: Expose a service in one VPC privately to consumers in other VPCs or accounts without peering.
Reference Design for Application VPCs:
- Three or four subnets per AZ: public (ALB, NAT), private-app (EC2/EKS/Fargate), private-data (RDS, ElastiCache), optional private-isolated (no internet at all).
- One NAT Gateway per AZ for availability and to avoid cross-AZ data-transfer cost.
- VPC Flow Logs to S3 or CloudWatch for auditing and incident response.
- Interface endpoints for STS, ECR, Secrets Manager, Systems Manager — reduces NAT traffic and eliminates a public-internet dependency.
Common Gotchas:
- Overlapping CIDR ranges break peering and Transit Gateway — plan address space across accounts up front (IPAM helps).
- NAT Gateway data-processing charges add up — prefer VPC endpoints for S3/DynamoDB.
- Lambda-in-VPC has a warm-pool model now, but still adds cold-start and ENI cost — only attach when it must reach VPC resources.
- Default security groups are permissive between attached resources — always create explicit SGs per role.
Service Limits & Quotas:
- VPCs per region: 5 by default (soft); raisable.
- Subnets per VPC: 200 (soft).
- CIDR blocks per VPC: 5 IPv4 by default (max 50), 5 IPv6 (max 5).
- Route tables per VPC: 200 (soft); routes per table 50 (soft, max 1,000).
- Security groups per VPC: 2,500 (soft); rules per SG 60 inbound + 60 outbound (soft).
- Security groups per ENI: 5 by default, max 16.
- Network ACLs per VPC: 200; rules per NACL 20 (max 40).
- NAT Gateways per AZ: 5; bandwidth scales 5–100 Gbps per NAT GW.
- Internet Gateways: 1 per VPC.
- Transit Gateway attachments: 5,000 per TGW; routes 10,000 per route table.
- VPC peering connections: 50 per VPC by default (soft, raisable to 125).
Pricing Model:
- VPC itself: Free — no charge for the VPC, subnets, route tables, security groups, NACLs, or Internet Gateway.
- NAT Gateway: ~$0.045/hour per NAT GW plus ~$0.045/GB processed — typically the largest VPC cost item.
- VPC Interface Endpoints (PrivateLink): ~$0.01/hour per endpoint per AZ plus ~$0.01/GB processed.
- VPC Gateway Endpoints (S3, DynamoDB): Free — always use these for S3/DynamoDB traffic.
- Transit Gateway: ~$0.05/hour per attachment plus ~$0.02/GB processed.
- Site-to-Site VPN: ~$0.05/hour per connection plus standard data transfer.
- Direct Connect: Per-port-hour (varies by speed) plus per-GB outbound.
- Data transfer: Cross-AZ ~$0.01/GB each way; cross-region ~$0.02/GB; outbound to internet from $0.09/GB tiering down with volume.
- VPC Flow Logs: Storage cost in S3/CloudWatch; CloudWatch ingestion ~$0.50/GB.
- Common cost surprises: NAT Gateway data processing on chatty workloads (image pulls, S3 traffic without endpoints), cross-AZ traffic between app and data tiers, idle Elastic IPs ($0.005/hour after 2024), Flow Logs in CloudWatch at high volume, and forgetting to delete unused interface endpoints replicated across 3 AZs.
Code Example:
A minimal Terraform-style configuration creating a VPC with public and private subnets across 2 AZs and a single NAT Gateway. Using AWS CLI for clarity:
# 1) Create the VPC
VPC_ID=$(aws ec2 create-vpc \
--cidr-block 10.0.0.0/16 \
--tag-specifications 'ResourceType=vpc,Tags=[{Key=Name,Value=app-vpc}]' \
--query 'Vpc.VpcId' --output text)
aws ec2 modify-vpc-attribute --vpc-id $VPC_ID --enable-dns-hostnames
# 2) Public + private subnets in two AZs
PUB_A=$(aws ec2 create-subnet --vpc-id $VPC_ID \
--cidr-block 10.0.0.0/24 --availability-zone us-west-2a \
--query 'Subnet.SubnetId' --output text)
PUB_B=$(aws ec2 create-subnet --vpc-id $VPC_ID \
--cidr-block 10.0.1.0/24 --availability-zone us-west-2b \
--query 'Subnet.SubnetId' --output text)
PRIV_A=$(aws ec2 create-subnet --vpc-id $VPC_ID \
--cidr-block 10.0.10.0/24 --availability-zone us-west-2a \
--query 'Subnet.SubnetId' --output text)
PRIV_B=$(aws ec2 create-subnet --vpc-id $VPC_ID \
--cidr-block 10.0.11.0/24 --availability-zone us-west-2b \
--query 'Subnet.SubnetId' --output text)
# 3) IGW + default route for the public subnets
IGW_ID=$(aws ec2 create-internet-gateway \
--query 'InternetGateway.InternetGatewayId' --output text)
aws ec2 attach-internet-gateway --vpc-id $VPC_ID --internet-gateway-id $IGW_ID
PUB_RT=$(aws ec2 create-route-table --vpc-id $VPC_ID \
--query 'RouteTable.RouteTableId' --output text)
aws ec2 create-route --route-table-id $PUB_RT \
--destination-cidr-block 0.0.0.0/0 --gateway-id $IGW_ID
# 4) S3 Gateway Endpoint — free egress to S3
aws ec2 create-vpc-endpoint --vpc-id $VPC_ID \
--service-name com.amazonaws.us-west-2.s3 \
--route-table-ids $PUB_RT
Common Interview Questions:
What is the difference between a Security Group and a Network ACL?
Security Groups are stateful and instance-level — they track flows so return traffic is implicitly allowed; they support allow rules only. NACLs are stateless and subnet-level — both directions must be explicitly allowed; they support both allow and deny rules and are evaluated in numeric order. SGs handle 95% of access control; NACLs are useful for broad deny patterns at the subnet edge.
How do public and private subnets actually differ?
The distinction is purely about routing. A subnet is "public" if its route table has a default route (0.0.0.0/0) pointing to an Internet Gateway and instances have public IPs. A subnet is "private" if its default route points to a NAT Gateway (egress-only) or has no internet route. AWS doesn't explicitly tag subnets — it's a convention based on routing.
VPC Peering vs. Transit Gateway — when to use each?
VPC Peering is point-to-point and non-transitive — fine for two or three VPCs. Beyond that, the mesh becomes unmanageable (n*(n-1)/2 connections). Transit Gateway is a hub-and-spoke router; each VPC attaches once and TGW handles all routing. TGW is also the bridge to Direct Connect and VPN. Peering is free for traffic; TGW costs per attachment-hour and per GB.
What is a VPC Endpoint and why use one?
A VPC Endpoint provides private connectivity from your VPC to AWS services without traversing the public internet or NAT. Two types: Gateway Endpoints (free, only for S3 and DynamoDB) and Interface Endpoints (paid, PrivateLink, for almost every other service). Using endpoints reduces NAT data-processing fees, eliminates a public-internet dependency, and lets private subnets call AWS APIs.
How would you design VPC CIDR blocks for a multi-account organization?
Centrally allocate non-overlapping CIDRs from a master IPAM pool (AWS IPAM helps). Reserve clear regions in the address space (e.g., 10.0.0.0/8 for AWS, segmented per environment and account). Avoid the common 10.0.0.0/16 default in every account because it'll bite you the moment you peer or use Transit Gateway. Leave headroom — VPC CIDRs cannot overlap their attached extension blocks either.
How does NAT Gateway pricing trip people up?
NAT GW costs per-hour and per-GB-processed. Workloads that pull large container images, push logs to non-VPC destinations, or fetch packages from public repos can rack up hundreds or thousands of dollars per month. Mitigations: S3 Gateway Endpoints (free), ECR Interface Endpoints, pull-through cache, route logs to CloudWatch via interface endpoint, and one NAT per AZ (not per region) to avoid cross-AZ surcharges on top.