VPC is your private network within AWS. Every resource you create (EC2, RDS, Lambda in VPC) lives inside a VPC. You control IP ranges, routing, and what can reach what.
Real-World: Your 3-tier app: public subnets for the load balancer, private subnets for EC2 app servers, isolated subnets for RDS. RDS has NO internet access — only the app servers can reach it.
VPC: 10.0.0.0/16 (65,534 usable IPs)
├── Public Subnet AZ-A: 10.0.1.0/24
│ ├── EC2 (web server)
│ └── NAT Gateway
├── Public Subnet AZ-B: 10.0.2.0/24
├── Private Subnet AZ-A: 10.0.11.0/24
│ ├── EC2 (app server)
│ └── RDS Primary
└── Private Subnet AZ-B: 10.0.12.0/24
└── RDS Standby (Multi-AZ)
- Enables internet access for resources in public subnets
- Attached to VPC (one per VPC)
- Route table must include
0.0.0.0/0 → IGW
- Allows private subnet resources to reach internet (outbound only)
- Placed in public subnet
- Private subnet route table:
0.0.0.0/0 → NAT Gateway - Internet can NOT initiate connections to private resources
- Regional — one per AZ for HA (failure of NAT = no internet for that AZ's private resources)
Public Subnet Route Table:
10.0.0.0/16 → local
0.0.0.0/0 → igw-abc123
Private Subnet Route Table:
10.0.0.0/16 → local
0.0.0.0/0 → nat-gateway-xyz
- Stateful: if you allow inbound, outbound response is automatically allowed
- Applied to instances/ENIs
- Only Allow rules (no explicit deny)
- Evaluate all rules before deciding
EC2 App Server SG:
Inbound: Port 80 from ALB-SG (not 0.0.0.0/0!)
Inbound: Port 443 from ALB-SG
Outbound: Port 5432 to RDS-SG (PostgreSQL)
Outbound: Port 443 to 0.0.0.0/0 (HTTPS for external APIs)
Chaining SGs: Reference SG ID as source, not IP range. When new EC2 instances are added to ALB-SG, they automatically can reach App Server SG.
- Stateless: must allow both inbound AND outbound for two-way communication
- Applied to subnets (not instances)
- Has both Allow AND Deny rules
- Rules evaluated in number order (lowest first)
- Deny specific IPs: add DENY rule with lower number than ALLOW
NACL for Public Subnet:
Rule 100: Allow Inbound TCP 80 0.0.0.0/0
Rule 110: Allow Inbound TCP 443 0.0.0.0/0
Rule 120: Allow Inbound TCP 1024-65535 0.0.0.0/0 (ephemeral ports for return traffic)
Rule 200: Deny Inbound ALL 1.2.3.4/32 (blocked IP)
Rule *: Deny ALL ALL (implicit deny)
| Feature | Security Group | NACL |
|---|---|---|
| Level | Instance/ENI | Subnet |
| State | Stateful | Stateless |
| Rules | Allow only | Allow + Deny |
| Processing | All rules evaluated | Rules in order (stop at first match) |
| Default | All outbound allowed | All traffic allowed |
Direct network connection between two VPCs (same or different account/region):
VPC-A (10.0.0.0/16) ←→ Peering ←→ VPC-B (172.16.0.0/16)
Key rules:
- CIDR ranges must NOT overlap
- NOT transitive: A↔B and B↔C does NOT mean A↔C
- Add route table entries in BOTH VPCs
Access AWS services without internet — traffic stays in AWS network:
- Creates ENI in your subnet
- Supports most AWS services (S3, DynamoDB, SSM, Secrets Manager, etc.)
- Uses private DNS —
s3.amazonaws.comresolves to private IP - Cost: hourly + per-GB charge
- S3 and DynamoDB ONLY
- Free
- Add to route table:
com.amazonaws.us-east-1.s3 → gateway-endpoint - No ENI created
# Why use it?
Lambda in VPC needs S3 → normally routes through NAT Gateway ($0.045/GB)
With S3 Gateway Endpoint → traffic stays in AWS, FREE
Huge cost savings for high-throughput S3 access from VPC
| Option | How | Latency | Use for |
|---|---|---|---|
| Site-to-Site VPN | IPSec over internet | Variable | Small/medium data, quick setup |
| Client VPN | OpenVPN from laptop | Variable | Developer access to VPC |
| Direct Connect | Dedicated fiber | Consistent, low | High throughput, consistent latency |
| Direct Connect + VPN | DX as backup | Best of both | Production HA |
| Practice | Reason |
|---|---|
| Use SG references (not IP ranges) for inter-service | Dynamic IP handling |
| Place RDS in private subnet with no route to internet | Minimize attack surface |
| One NAT Gateway per AZ | AZ resilience |
| Use VPC Endpoints for S3/DynamoDB | Cost savings + security |
| Enable VPC Flow Logs | Network troubleshooting + security audit |
| Use smaller subnets per tier | Easier IP management |
- SG is stateful — responses allowed automatically. NACL is stateless — must allow both directions.
- NACLs block specific IPs — SGs can't deny. If question says "block IP", it's NACL.
- Gateway Endpoint = FREE for S3/DynamoDB. Interface Endpoint has hourly cost.
- VPC Peering is not transitive — most tested fact about peering.
- 0.0.0.0/0 → IGW makes a subnet public. Private subnets have 0.0.0.0/0 → NAT or no route at all.
- Lambda in VPC: needs ENI in private subnet + NAT Gateway for internet access.
- Ephemeral ports: NACLs must allow 1024-65535 inbound for return traffic from internet.
Q: Block a specific IP from reaching your EC2? → Add NACL Deny rule for that IP (SGs can't deny).
Q: Private subnet Lambda can't reach the internet? → Add NAT Gateway in public subnet, add route in private subnet to NAT.
Q: S3 access from private EC2 should NOT go through internet? → Create S3 Gateway Endpoint, add to route table.
Q: Two VPCs in same account can't communicate? → Create VPC Peering connection, add route table entries in both VPCs, check SGs.