All topics
Cloud · Learning hub

VPC notes for developers

Master VPC with a curated set of 3 developer notes — core concepts, patterns, and interview prep. Maintained by the DevRecall team.

Save this stack to your DevRecallMore Cloud notes
VPC

Subnets, Route Tables & Internet Access

AWS VPC: Subnets, Route Tables & Internet Access A VPC (Virtual Private Cloud) is a logically isolated network in AWS. You define the IP range, subnets, routing

AWS VPC: Subnets, Route Tables & Internet Access

A VPC (Virtual Private Cloud) is a logically isolated network in AWS. You define the IP range, subnets, routing, and access controls. All EC2 instances, RDS databases, and most other services run inside a VPC.

VPC & Subnet Concepts

VPC
  - CIDR block: your private IP range, e.g. 10.0.0.0/16 (65,536 IPs)
  - Can have multiple subnets across AZs
  - Default VPC: auto-created per region (172.31.0.0/16), avoid for production

Subnet
  - Subdivision of VPC in a single AZ
  - Public subnet:  has route to Internet Gateway → instances can be internet-facing
  - Private subnet: no route to IGW → instances hidden from internet
  - AWS reserves 5 IPs per subnet (first 4 + last 1)

Typical multi-AZ layout (10.0.0.0/16):
  Public subnet AZ-a:   10.0.1.0/24  (254 usable IPs)
  Public subnet AZ-b:   10.0.2.0/24
  Private subnet AZ-a:  10.0.11.0/24
  Private subnet AZ-b:  10.0.12.0/24
  DB subnet AZ-a:       10.0.21.0/24
  DB subnet AZ-b:       10.0.22.0/24

Route Tables & Internet Gateway

# Create VPC
aws ec2 create-vpc --cidr-block 10.0.0.0/16
# Note the VpcId

# Create subnets
aws ec2 create-subnet   --vpc-id vpc-0abc123   --cidr-block 10.0.1.0/24   --availability-zone us-east-1a
  # Note SubnetId

# Internet Gateway (IGW) — enables public internet access
aws ec2 create-internet-gateway
aws ec2 attach-internet-gateway   --internet-gateway-id igw-0abc123   --vpc-id vpc-0abc123

# Route table for public subnets
aws ec2 create-route-table --vpc-id vpc-0abc123
# Add route: all traffic → IGW
aws ec2 create-route   --route-table-id rtb-0abc123   --destination-cidr-block 0.0.0.0/0   --gateway-id igw-0abc123
# Associate with public subnet
aws ec2 associate-route-table   --route-table-id rtb-0abc123   --subnet-id subnet-0abc123

# Enable auto-assign public IP on public subnet
aws ec2 modify-subnet-attribute   --subnet-id subnet-0abc123   --map-public-ip-on-launch

NAT Gateway (Private Subnet Outbound)

A NAT Gateway lets instances in private subnets initiate outbound internet connections (for updates, APIs) without being reachable from the internet.

# Create Elastic IP for NAT Gateway
aws ec2 allocate-address --domain vpc

# Create NAT Gateway in PUBLIC subnet
aws ec2 create-nat-gateway   --subnet-id subnet-0public123   --allocation-id eipalloc-0abc123

# Add route in PRIVATE subnet route table → NAT Gateway
aws ec2 create-route   --route-table-id rtb-0private123   --destination-cidr-block 0.0.0.0/0   --nat-gateway-id nat-0abc123

# NAT costs: ~$0.045/hour + $0.045/GB data processed
# For dev: use NAT Instance (cheaper) or VPC Endpoints for S3/DynamoDB (free egress)

# VPC Endpoint (free access to S3 without internet)
aws ec2 create-vpc-endpoint   --vpc-id vpc-0abc123   --service-name com.amazonaws.us-east-1.s3   --route-table-ids rtb-0private123
VPC

Security Groups, NACLs & Flow Logs

AWS VPC: Security Groups, NACLs & Flow Logs Security Groups Security groups are stateful firewalls attached to EC2 instances, RDS, etc. Rules are evaluated as a

AWS VPC: Security Groups, NACLs & Flow Logs

Security Groups

Security groups are stateful firewalls attached to EC2 instances, RDS, etc. Rules are evaluated as a whole — if any rule allows the traffic, it's permitted. Deny rules are not possible.

# Create security group
aws ec2 create-security-group   --group-name web-sg   --description "Web server security group"   --vpc-id vpc-0abc123

# Add inbound rules
aws ec2 authorize-security-group-ingress   --group-id sg-0abc123   --protocol tcp   --port 80   --cidr 0.0.0.0/0

aws ec2 authorize-security-group-ingress   --group-id sg-0abc123   --protocol tcp   --port 443   --cidr 0.0.0.0/0

# Allow SSH from specific IP
aws ec2 authorize-security-group-ingress   --group-id sg-0abc123   --protocol tcp   --port 22   --cidr 203.0.113.0/32

# Reference another SG (allow app-sg to connect to db-sg on 5432)
aws ec2 authorize-security-group-ingress   --group-id sg-db123   --protocol tcp   --port 5432   --source-group sg-app123

# Describe rules
aws ec2 describe-security-group-rules --filter Name=group-id,Values=sg-0abc123

# Revoke rule
aws ec2 revoke-security-group-ingress   --group-id sg-0abc123   --protocol tcp   --port 22   --cidr 0.0.0.0/0

Network ACLs (NACLs)

NACLs are stateless subnet-level firewalls. Both inbound AND outbound rules must explicitly allow traffic. Rules are evaluated in order by rule number (lowest first).

Security Groups vs NACLs:
                     Security Group           NACL
  Level:             Instance (ENI)           Subnet
  State:             Stateful (return         Stateless (must allow
                     traffic auto-allowed)     return traffic too)
  Allow/Deny:        Allow only               Allow AND Deny
  Rule evaluation:   All rules together       In order (100, 200, ...)
  Default:           Deny all in, all out     Allow all in, all out

NACL use cases:
  - Block specific IP addresses (can't do this with SG)
  - Add extra defense-in-depth at subnet boundary
  - Emergency "shut off" — deny all ingress on subnet
# Add inbound deny rule (rule 50 evaluated before allow rules)
aws ec2 create-network-acl-entry   --network-acl-id acl-0abc123   --rule-number 50   --protocol tcp   --rule-action deny   --ingress   --cidr-block 192.168.1.0/24   --port-range From=0,To=65535

# Ephemeral ports must be allowed for return traffic (1024-65535)
aws ec2 create-network-acl-entry   --network-acl-id acl-0abc123   --rule-number 200   --protocol tcp   --rule-action allow   --egress   --cidr-block 0.0.0.0/0   --port-range From=1024,To=65535

VPC Flow Logs

Flow logs capture IP traffic information for network interfaces, subnets, or VPCs. Essential for security analysis and troubleshooting.

# Create flow log (to CloudWatch Logs)
aws ec2 create-flow-logs   --resource-type VPC   --resource-ids vpc-0abc123   --traffic-type ALL   --log-destination-type cloud-watch-logs   --log-destination arn:aws:logs:us-east-1:123456789:log-group:/vpc/flowlogs   --deliver-logs-permission-arn arn:aws:iam::123456789:role/FlowLogsRole

# Or to S3 (cheaper for long retention)
aws ec2 create-flow-logs   --resource-type VPC   --resource-ids vpc-0abc123   --traffic-type REJECT   --log-destination-type s3   --log-destination arn:aws:s3:::my-flow-logs-bucket/vpc/

# Flow log record format:
# version accountid interface-id srcaddr dstaddr srcport dstport protocol
# packets bytes windowstart windowend action flowdirection log-status

# Example: REJECT record
# 2 123456789012 eni-abc123 203.0.113.1 10.0.1.5 45678 22 6 1 40 ... REJECT INGRESS OK

# Query with CloudWatch Logs Insights
# fields @timestamp, srcAddr, dstAddr, dstPort, action
# | filter action = "REJECT"
# | stats count() by srcAddr
# | sort count desc
VPC

VPN, Peering & Advanced Networking

AWS VPC: VPN, Peering & Advanced Networking VPC Peering VPC peering connects two VPCs so resources can communicate using private IPs — no internet, no NAT, no V

AWS VPC: VPN, Peering & Advanced Networking

VPC Peering

VPC peering connects two VPCs so resources can communicate using private IPs — no internet, no NAT, no VPN. Works across accounts and regions.

# Create peering connection (requester VPC)
aws ec2 create-vpc-peering-connection   --vpc-id vpc-0abc123   --peer-vpc-id vpc-0xyz789   --peer-owner-id 987654321012   --peer-region us-west-2   # omit for same region

# Accept peering request (accepter side)
aws ec2 accept-vpc-peering-connection   --vpc-peering-connection-id pcx-0abc123   --region us-west-2

# Add routes in BOTH VPCs (peering is NOT transitive)
aws ec2 create-route   --route-table-id rtb-vpc-a   --destination-cidr-block 10.1.0.0/16   --vpc-peering-connection-id pcx-0abc123

aws ec2 create-route   --route-table-id rtb-vpc-b   --destination-cidr-block 10.0.0.0/16   --vpc-peering-connection-id pcx-0abc123

# IMPORTANT: CIDRs must NOT overlap for peering to work
# Peering is NOT transitive: A↔B, B↔C does NOT mean A↔C

Transit Gateway

Transit Gateway is a hub-and-spoke network transit hub. Connect many VPCs, VPNs, and Direct Connect without N*(N-1)/2 peering connections.

# Create Transit Gateway
aws ec2 create-transit-gateway   --description "Central hub"   --options DefaultRouteTableAssociation=enable,DefaultRouteTablePropagation=enable

# Attach VPCs
aws ec2 create-transit-gateway-vpc-attachment   --transit-gateway-id tgw-0abc123   --vpc-id vpc-0abc123   --subnet-ids subnet-0a subnet-0b

# Add route in VPC route table → TGW
aws ec2 create-route   --route-table-id rtb-0abc123   --destination-cidr-block 10.0.0.0/8   --transit-gateway-id tgw-0abc123

Site-to-Site VPN

# 1. Create Customer Gateway (your on-premises VPN device)
aws ec2 create-customer-gateway   --bgp-asn 65000   --ip-address 203.0.113.5   --type ipsec.1

# 2. Create Virtual Private Gateway (attach to VPC)
aws ec2 create-vpn-gateway --type ipsec.1
aws ec2 attach-vpn-gateway   --vpn-gateway-id vgw-0abc123   --vpc-id vpc-0abc123

# 3. Create VPN connection
aws ec2 create-vpn-connection   --type ipsec.1   --customer-gateway-id cgw-0abc123   --vpn-gateway-id vgw-0abc123   --options StaticRoutesOnly=false  # use BGP

# 4. Download VPN config for your device
aws ec2 download-vpn-configuration   --vpn-connection-id vpn-0abc123   --output text

Key Design Decisions

  • CIDR planning: choose non-overlapping ranges across all VPCs upfront — peering/TGW won't work with overlapping CIDRs.

  • AZ spread: put subnets in at least 2 AZs. For critical services, use 3 AZs.

  • VPC Endpoints: use for S3 and DynamoDB (Gateway endpoints = free); use Interface Endpoints for other services inside the VPC.

  • NAT Gateway per AZ: place one NAT GW in each AZ to avoid cross-AZ data transfer charges and single point of failure.

  • Private DNS: Route 53 Private Hosted Zones resolve internal service names within VPC.

  • AWS PrivateLink: expose a service privately to other VPCs/accounts without VPC peering or internet exposure.

  • Direct Connect: dedicated private fiber from on-premises to AWS — lower latency, consistent throughput, better for compliance than VPN.

  • Security group best practice: create purpose-specific SGs (web-sg, app-sg, db-sg) and reference by ID, not CIDR.

Keep your VPC knowledge sharp.

Save this stack to your personal DevRecall — add your own notes, track what you're learning, and share what you know with the community.

Get started — free forever