Skip to content

Networking

This document describes the VPC architecture, subnets, security groups, routing, and network security for MenoTime. The design follows AWS security best practices with clear separation between public and private resources.

VPC Architecture

VPC: menotime-vpc (CIDR: 10.0.0.0/16)

┌────────────────────────────────────────────────────────┐
│          menotime-vpc (10.0.0.0/16)                    │
├────────────────────────────────────────────────────────┤
│                                                        │
│  ┌──────────────────────────────────────────────────┐ │
│  │  Public Subnets (Tier 1)                         │ │
│  ├──────────────────────────────────────────────────┤ │
│  │  us-west-1a: 10.0.1.0/24                        │ │
│  │  ├─ ALB Subnet (primary)                        │ │
│  │  ├─ NAT Gateway (outbound for private subnets) │ │
│  │  └─ Internet Gateway route                      │ │
│  │                                                  │ │
│  │  us-west-1b: 10.0.2.0/24                        │ │
│  │  ├─ ALB Subnet (secondary)                      │ │
│  │  ├─ NAT Gateway (redundancy)                    │ │
│  │  └─ Internet Gateway route                      │ │
│  └──────────────────────────────────────────────────┘ │
│           ↓                                            │
│  ┌──────────────────────────────────────────────────┐ │
│  │  Private Subnets (Tier 2) - ECS Tasks            │ │
│  ├──────────────────────────────────────────────────┤ │
│  │  us-west-1a: 10.0.11.0/24                       │ │
│  │  ├─ ECS Tasks (no IGW access)                   │ │
│  │  ├─ NAT Gateway outbound (via pub 10.0.1.0/24) │ │
│  │  └─ Secrets Manager, S3 (via VPC Endpoints)    │ │
│  │                                                  │ │
│  │  us-west-1b: 10.0.12.0/24                       │ │
│  │  ├─ ECS Tasks (no IGW access)                   │ │
│  │  ├─ NAT Gateway outbound (via pub 10.0.2.0/24) │ │
│  │  └─ Secrets Manager, S3 (via VPC Endpoints)    │ │
│  └──────────────────────────────────────────────────┘ │
│           ↓                                            │
│  ┌──────────────────────────────────────────────────┐ │
│  │  Private Subnets (Tier 3) - Database             │ │
│  ├──────────────────────────────────────────────────┤ │
│  │  us-west-1a: 10.0.21.0/24                       │ │
│  │  └─ RDS PostgreSQL (replica in Multi-AZ mode)   │ │
│  │                                                  │ │
│  │  us-west-1b: 10.0.22.0/24                       │ │
│  │  └─ RDS PostgreSQL (primary in Multi-AZ mode)   │ │
│  │                                                  │ │
│  │  Note: No internet access; accessed only from   │ │
│  │  ECS tasks via RDS security group               │ │
│  └──────────────────────────────────────────────────┘ │
│                                                        │
└────────────────────────────────────────────────────────┘

Subnet Details

Public Subnets (ALB & NAT Gateways)

Subnet CIDR AZ Purpose
menotime-pub-a 10.0.1.0/24 us-west-1a ALB, NAT GW
menotime-pub-b 10.0.2.0/24 us-west-1b ALB, NAT GW (redundancy)

Route Table (menotime-public-rt):

Destination     | Target | Purpose
0.0.0.0/0       | IGW    | Internet access (HTTP/HTTPS)
10.0.0.0/16     | Local  | VPC internal routing

Available IPs per subnet: - Total: 256 addresses (10.0.1.0 - 10.0.1.255) - Usable: 251 (AWS reserves 5 per subnet) - Used: ~10 (ALB ENI + NAT Gateway + bastion if applicable)

Private Subnets (ECS Tasks)

Subnet CIDR AZ Purpose
menotime-priv-ecs-a 10.0.11.0/24 us-west-1a ECS tasks
menotime-priv-ecs-b 10.0.12.0/24 us-west-1b ECS tasks

Route Table (menotime-private-ecs-rt):

Destination     | Target | Purpose
0.0.0.0/0       | NAT-GW | Outbound to internet (ECR pulls, SES)
10.0.0.0/16     | Local  | VPC internal routing

Network ACLs (default allow all): - Inbound: Allow from public subnets (ALB) - Inbound: Allow from database subnets (rare) - Outbound: Allow to public subnets, external services

Private Subnets (Database)

Subnet CIDR AZ Purpose
menotime-priv-db-a 10.0.21.0/24 us-west-1a RDS PostgreSQL
menotime-priv-db-b 10.0.22.0/24 us-west-1b RDS PostgreSQL

Route Table (menotime-private-db-rt):

Destination     | Target | Purpose
10.0.0.0/16     | Local  | VPC internal routing only

Network ACLs: - Inbound: Allow PostgreSQL (5432) from private ECS subnets only - Outbound: Deny all (database doesn't initiate connections)


Internet Gateway & NAT Gateway

Internet Gateway (IGW)

Name: menotime-igw

Purpose: Enables public internet access for public subnets

Configuration: - Attached to menotime-vpc - Route in public route table: 0.0.0.0/0 → IGW

Traffic Flow:

Client (Internet)
  ↓ (HTTPS 443)
CloudFront/ALB (in public subnet, us-west-1a)
  ↓ (via IGW)
Internet
  ↓ (responses)
ALB processes and routes to ECS

NAT Gateway (Network Address Translation)

Primary: menotime-nat-gw-a in public subnet 10.0.1.0/24

Secondary (redundancy): menotime-nat-gw-b in public subnet 10.0.2.0/24

Purpose: Allows private subnet resources (ECS tasks, RDS) to reach external services while remaining unreachable from the internet

Configuration: - Elastic IP: 52.xxx.yyy.zzz (static public IP) - Subnet: Public subnet (us-west-1a for primary, us-west-1b for secondary)

Usage: - ECS tasks pulling Docker images from ECR (internet) - ECS tasks sending emails via SES (internet) - RDS snapshots copying to S3 (internal but routed through NAT)

Traffic Flow:

ECS Task (10.0.11.10)
  ↓ (request to external service)
NAT Gateway (10.0.1.xxx → 52.xxx.yyy.zzz)
  ↓ (outbound via IGW)
External Service (e.g., ECR.us-west-1.amazonaws.com)
  ↓ (response to 52.xxx.yyy.zzz)
NAT Gateway (translates back to 10.0.11.10)
  ↓
ECS Task receives response

Cost: ~$32/month per NAT Gateway + data processing charges


Security Groups

ALB Security Group

Name: menotime-alb-sg

Purpose: Public-facing load balancer; accepts HTTP/HTTPS from internet

Inbound Rules:

Protocol | Port | Source | Purpose
---------|------|--------|----------
HTTP     | 80   | 0.0.0.0/0 | Redirect to HTTPS
HTTPS    | 443  | 0.0.0.0/0 | Client connections

Outbound Rules:

Protocol | Port | Destination | Purpose
---------|------|-------------|----------
TCP      | 8000 | menotime-ecs-sg | Forward to ECS tasks

ECS Security Group

Name: menotime-ecs-sg

Purpose: Container tasks; accepts traffic from ALB and initiates connections to external services

Inbound Rules:

Protocol | Port | Source | Purpose
---------|------|--------|----------
TCP      | 8000 | menotime-alb-sg | Health checks, requests from ALB

Outbound Rules:

Protocol | Port | Destination | Purpose
---------|------|-------------|----------
TCP      | 5432 | menotime-db-sg | Database connections
TCP      | 443  | 0.0.0.0/0 | HTTPS to AWS services (Secrets Manager, SES, S3, ECR)
TCP      | 587  | 0.0.0.0/0 | SMTP to SES
UDP      | 53   | 0.0.0.0/0 | DNS (Route 53)

RDS Security Group

Name: menotime-db-sg

Purpose: Database; accepts only PostgreSQL traffic from ECS tasks

Inbound Rules:

Protocol | Port | Source | Purpose
---------|------|--------|----------
TCP      | 5432 | menotime-ecs-sg | Database connections from ECS
TCP      | 5432 | menotime-bastion-sg | Bastion host (optional, operational access)

Outbound Rules:

Protocol | Port | Destination | Purpose
---------|------|-------------|----------
(none)   |      | Deny all | RDS doesn't initiate connections

Bastion Security Group (Optional)

Name: menotime-bastion-sg

Purpose: Jump host for operational database access (alternative to SSM Session Manager)

Inbound Rules:

Protocol | Port | Source | Purpose
---------|------|--------|----------
TCP      | 22   | YourIP/32 | SSH from specific office/VPN

Outbound Rules:

Protocol | Port | Destination | Purpose
---------|------|-------------|----------
TCP      | 5432 | menotime-db-sg | Database access
TCP      | 443  | 0.0.0.0/0 | HTTPS (updates, etc.)

VPC Endpoints

VPC Endpoints allow private subnet resources to access AWS services without internet traversal.

S3 Gateway Endpoint

Name: menotime-s3-gateway-endpoint

Purpose: ECS tasks access S3 for logs and backups without NAT Gateway data charges

Configuration: - Service: com.amazonaws.us-west-1.s3 - Route Table Association: menotime-private-ecs-rt - Policy: Allow S3 buckets: menotime-logs, menotime-backups, menotime-static-assets

Route Added:

Destination       | Target
s3.us-west-1.* | menotime-s3-gateway-endpoint

Secrets Manager Interface Endpoint

Name: menotime-secretsmanager-endpoint

Purpose: ECS tasks retrieve database credentials from Secrets Manager privately

Configuration: - Service: com.amazonaws.us-west-1.secretsmanager - Subnets: Private ECS subnets (10.0.11.0/24, 10.0.12.0/24) - Security Group: Allow HTTPS (443) from menotime-ecs-sg

ECR Interface Endpoint

Name: menotime-ecr-endpoint

Purpose: ECS pulls container images from ECR privately (avoids NAT GW charges)

Configuration: - Service: com.amazonaws.us-west-1.ecr.dkr (registry) + com.amazonaws.us-west-1.ecr.api (API) - Subnets: Private ECS subnets - Security Group: Allow HTTPS (443) from menotime-ecs-sg


ALB Configuration

Application Load Balancer

Name: menotime-alb

Subnets: Public subnets (10.0.1.0/24, 10.0.2.0/24)

Security Group: menotime-alb-sg

Scheme: Internet-facing

ALB Listeners

Listener 1: HTTP (Port 80)

Protocol: HTTP
Port: 80
Default Action: Redirect to HTTPS (301)
Target: None (redirect only)

Listener 2: HTTPS (Port 443)

Protocol: HTTPS
Port: 443
SSL Certificate: ACM certificate for menotime.ai
SSL Policy: ELBSecurityPolicy-TLS-1-2-2017-01
Default Action: Forward to Target Group
Target Group: menotime-backend-tg

Target Group Configuration

Name: menotime-backend-tg

Protocol: HTTP (targets are ECS tasks on port 8000)

Port: 8000

VPC: menotime-vpc

Health Check:

Protocol: HTTP
Path: /health
Interval: 30 seconds
Timeout: 5 seconds
Healthy Threshold: 2
Unhealthy Threshold: 3
Matcher: 200 (HTTP 200 response required)

Stickiness: Disabled (stateless API)

Deregistration Delay: 30 seconds (graceful connection drain)


DNS Configuration

Route 53 Hosted Zone

Zone: menotime.ai (public)

Record Types:

Name Type Value TTL Purpose
menotime.ai A CloudFront Distribution ID (alias) Root domain → CloudFront
www.menotime.ai CNAME menotime.ai 300 www subdomain → root
api.menotime.ai A ALB DNS Name (alias) API direct endpoint (optional)
dev-api.menotime.ai CNAME ALB DNS (dev) 300 Dev environment API
staging-api.menotime.ai CNAME ALB DNS (staging) 300 Staging environment API

DNSSEC

Status: Disabled (optional; can be enabled for enhanced security)


Traffic Flow Examples

Public User Request

User Browser (203.0.113.5)
  ↓ HTTPS to menotime.ai
Route 53 DNS Resolution
  ↓ Returns CloudFront Distribution IP
CloudFront Edge Location (cached)
  ↓ Cache miss, fetch from origin (ALB)
Public Subnet (ALB)
  ↓ Port 443 → 8000 (via Security Group rule)
Private Subnet (ECS Task)
  ↓ FastAPI processes request
HTTP Response
  ↓ Back through ALB → CloudFront → User
User Browser receives HTML, assets cached by CloudFront

ECS Task External Egress (ECR Pull)

Private Subnet (ECS Task 10.0.11.50)
  ↓ Request to ECR API (ecr.us-west-1.amazonaws.com)
ECR Interface VPC Endpoint (10.0.11.xxx)
  ↓ HTTPS to AWS backend
AWS Service Network
  ↓ Response returned
ECS Task receives Docker image layers

Database Access

Private Subnet (ECS Task 10.0.11.50)
  ↓ PostgreSQL request (source: 10.0.11.50:ephemeral)
Private Subnet (RDS Instance 10.0.21.100)
  ↓ Security group allows menotime-ecs-sg
  ↓ Processes SQL query
HTTP Response (via internal network)
  ↓
ECS Task receives result set

Network Monitoring & Troubleshooting

VPC Flow Logs

Purpose: Monitor network traffic for debugging and security analysis

Configuration:

Source: All traffic to/from VPC
Destination: CloudWatch Logs (/aws/vpc/menotime-flow-logs)
Format: ${version} ${account-id} ${interface-id} ${srcaddr} ${dstaddr} ${srcport} ${dstport} ${protocol} ${packets} ${bytes} ${windowstart} ${windowend} ${action} ${tcpflags} ${type}
Retention: 7 days
Cost: ~$0.50/million records

Query Examples:

# Connections rejected by security groups
[version, account, interface_id, srcaddr, dstaddr, srcport, dstport, protocol, packets, bytes, windowstart, windowend, action="REJECT", tcpflags, type] |
filter srcaddr like "10.0.11"

# High traffic (data exfiltration check)
fields srcaddr, dstaddr, bytes |
stats sum(bytes) as total_bytes by srcaddr, dstaddr |
filter total_bytes > 1000000

Common Network Issues

Issue: ECS task cannot reach Secrets Manager

Debug:

# 1. Check security group allows HTTPS outbound
aws ec2 describe-security-groups \
  --group-ids sg-xxxxx \
  --query 'SecurityGroups[0].IpPermissionsEgress'

# 2. Verify VPC Endpoint is active
aws ec2 describe-vpc-endpoints \
  --filters "Name=vpc-id,Values=vpc-xxxxx" \
  --query 'VpcEndpoints[?ServiceName==`com.amazonaws.us-west-1.secretsmanager`]'

# 3. Check route table has endpoint route
aws ec2 describe-route-tables \
  --filters "Name=vpc-id,Values=vpc-xxxxx" \
  --query 'RouteTables[?Routes[?DestinationPrefixListId]].Routes'

Issue: ECS task cannot reach database

Debug:

# 1. Verify database security group allows source
aws ec2 describe-security-groups \
  --group-ids menotime-db-sg \
  --query 'SecurityGroups[0].IpPermissions'

# 2. Verify ECS task is in correct subnet
aws ecs describe-tasks \
  --cluster menotime-prod-cluster \
  --tasks `<task-arn>` \
  --query 'tasks[0].attachments[?name==`networkInterfaceId`]'

# 3. Check RDS endpoint is reachable
telnet menotime-prod.xxxxx.us-west-1.rds.amazonaws.com 5432

Issue: NAT Gateway route missing

Fix:

aws ec2 create-route \
  --route-table-id rtb-xxxxx \
  --destination-cidr-block 0.0.0.0/0 \
  --nat-gateway-id natgw-xxxxx

Network Security Best Practices

  1. Least Privilege: Security groups allow only required ports/protocols
  2. Segmentation: Database in isolated subnet, inaccessible from internet
  3. Encryption: All traffic encrypted (TLS in transit, KMS at rest)
  4. Monitoring: VPC Flow Logs enabled for audit and troubleshooting
  5. Redundancy: NAT Gateways in multiple AZs for high availability
  6. No Public IPs: ECS tasks and RDS have no public IPs (private subnets only)

Cost Optimization

Component Monthly Cost Optimization
ALB ~$16 Consider classic LB if traffic \<1M requests/month
NAT Gateway (2×) ~$64 VPC endpoints reduce data charges; consider Single NAT
VPC Endpoints ~$7-14 Reduce NAT data charges; ROI positive
Data Transfer ~$10-50 Optimize to reduce inter-AZ traffic
Total Network ~$97-144 ~15% of infrastructure cost

Summary

MenoTime's VPC provides: - Security: Public/private subnet separation, security groups, encryption - High Availability: Multi-AZ design with redundant NAT Gateways - Performance: VPC Endpoints reduce data transfer costs - Scalability: Room for expansion (10.0.0.0/16 = 65,536 IPs) - Compliance: Encrypted, auditable, isolated databases

For load balancer configuration, see AWS Architecture. For security and IAM, see same document.