Skip to content

TradAI Final Architecture - VPC & Networking

Version: 9.2.1 | Date: 2025-12-09


VPC Design Overview

CIDR Allocation

VPC/Subnet CIDR Block Purpose Hosts
VPC 10.0.0.0/16 Main VPC 65,536
Public Subnet AZ-1 10.0.1.0/24 ALB, NAT Instance 254
Public Subnet AZ-2 10.0.2.0/24 ALB, NAT Instance (standby) 254
Private Subnet AZ-1 10.0.11.0/24 ECS Tasks, Lambda 254
Private Subnet AZ-2 10.0.12.0/24 ECS Tasks, Lambda 254
Database Subnet AZ-1 10.0.20.0/24 RDS Primary 254
Database Subnet AZ-2 10.0.21.0/24 RDS Standby 254

Network Architecture Diagram

┌─────────────────────────────────────────────────────────────────────────────────┐
│                              VPC: 10.0.0.0/16                                    │
│                              Region: us-east-1                                   │
│                                                                                  │
│  ┌─────────────────────────────────────┐  ┌─────────────────────────────────────┐
│  │        AZ-1 (us-east-1a)            │  │        AZ-2 (us-east-1b)            │
│  │                                      │  │                                      │
│  │  ┌────────────────────────────────┐ │  │  ┌────────────────────────────────┐ │
│  │  │  PUBLIC SUBNET: 10.0.1.0/24    │ │  │  │  PUBLIC SUBNET: 10.0.2.0/24    │ │
│  │  │                                 │ │  │  │                                 │ │
│  │  │  ┌─────────────┐ ┌───────────┐ │ │  │  │  ┌─────────────┐ ┌───────────┐ │ │
│  │  │  │    ALB      │ │   NAT     │ │ │  │  │  │    ALB      │ │   NAT     │ │ │
│  │  │  │  (Target)   │ │ Instance  │ │ │  │  │  │  (Target)   │ │ (Standby) │ │ │
│  │  │  │             │ │ t4g.nano  │ │ │  │  │  │             │ │           │ │ │
│  │  │  └─────────────┘ └─────┬─────┘ │ │  │  │  └─────────────┘ └───────────┘ │ │
│  │  │                        │       │ │  │  │                                 │ │
│  │  │  Route: 0.0.0.0/0 → IGW        │ │  │  │  Route: 0.0.0.0/0 → IGW        │ │
│  │  └────────────────────────┼───────┘ │  │  └────────────────────────────────┘ │
│  │                           │         │  │                                      │
│  │  ┌────────────────────────┼───────┐ │  │  ┌────────────────────────────────┐ │
│  │  │  PRIVATE SUBNET: 10.0.11.0/24  │ │  │  │  PRIVATE SUBNET: 10.0.12.0/24  │ │
│  │  │                        │       │ │  │  │                                 │ │
│  │  │  ┌─────────────────────▼─────┐ │ │  │  │  ┌─────────────────────────┐   │ │
│  │  │  │    ECS Services           │ │ │  │  │  │    ECS Services          │  │ │
│  │  │  │    ├─ Backend API         │ │ │  │  │  │    ├─ Backend API        │  │ │
│  │  │  │    ├─ Data Collection     │ │ │  │  │  │    ├─ Data Collection    │  │ │
│  │  │  │    └─ MLflow              │ │ │  │  │  │    └─ MLflow             │  │ │
│  │  │  └───────────────────────────┘ │ │  │  │  └─────────────────────────┘   │ │
│  │  │                                 │ │  │  │                                 │ │
│  │  │  ┌───────────────────────────┐ │ │  │  │  ┌─────────────────────────┐   │ │
│  │  │  │    Lambda (VPC)           │ │ │  │  │  │    Lambda (VPC)          │  │ │
│  │  │  │    ├─ validate-strategy   │ │ │  │  │  │    (Same functions)      │  │ │
│  │  │  │    ├─ data-proxy          │ │ │  │  │  └─────────────────────────┘   │ │
│  │  │  │    └─ others...           │ │ │  │  │                                 │ │
│  │  │  └───────────────────────────┘ │ │  │  │                                 │ │
│  │  │                                 │ │  │  │                                 │ │
│  │  │  Route: 0.0.0.0/0 → NAT Inst.  │ │  │  │  Route: 0.0.0.0/0 → NAT Inst.  │ │
│  │  └─────────────────────────────────┘ │  │  └─────────────────────────────────┘ │
│  │                                      │  │                                      │
│  │  ┌─────────────────────────────────┐ │  │  ┌─────────────────────────────────┐ │
│  │  │  DATABASE SUBNET: 10.0.20.0/24  │ │  │  │  DATABASE SUBNET: 10.0.21.0/24  │ │
│  │  │                                  │ │  │  │                                  │ │
│  │  │  ┌────────────────────────────┐ │ │  │  │  ┌────────────────────────────┐ │ │
│  │  │  │    RDS PostgreSQL         │ │ │  │  │  │    RDS (Standby/Future)    │ │ │
│  │  │  │    (MLflow Backend)       │ │ │  │  │  │                            │ │ │
│  │  │  │    db.t4g.micro           │ │ │  │  │  │                            │ │ │
│  │  │  └────────────────────────────┘ │ │  │  │  └────────────────────────────┘ │ │
│  │  │                                  │ │  │  │                                  │ │
│  │  │  Route: No internet access       │ │  │  │  Route: No internet access       │ │
│  │  └─────────────────────────────────┘ │  │  └─────────────────────────────────┘ │
│  └─────────────────────────────────────┘  └─────────────────────────────────────┘
│                                                                                  │
│  ┌────────────────────────────────────────────────────────────────────────────┐ │
│  │                         VPC Endpoints                                       │ │
│  │                                                                             │ │
│  │  Gateway Endpoints (FREE):                                                  │ │
│  │  ├─ com.amazonaws.us-east-1.s3                                             │ │
│  │  └─ com.amazonaws.us-east-1.dynamodb                                       │ │
│  │                                                                             │ │
│  │  Interface Endpoints (Optional - use NAT instead for cost):                │ │
│  │  ├─ com.amazonaws.us-east-1.ecr.api        ($7/mo × 2 AZ = $14)           │ │
│  │  ├─ com.amazonaws.us-east-1.ecr.dkr        ($7/mo × 2 AZ = $14)           │ │
│  │  └─ com.amazonaws.us-east-1.secretsmanager ($7/mo × 2 AZ = $14)           │ │
│  │                                                                             │ │
│  │  RECOMMENDATION: Skip interface endpoints, use NAT Instance (saves $28/mo) │ │
│  └────────────────────────────────────────────────────────────────────────────┘ │
│                                                                                  │
│  ┌────────────────────────────────────────────────────────────────────────────┐ │
│  │                         Internet Gateway                                    │ │
│  │                         (Attached to VPC)                                   │ │
│  └────────────────────────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────────────────────┘
                                    INTERNET

Route Tables

Public Route Table

Destination Target Purpose
10.0.0.0/16 local VPC internal traffic
0.0.0.0/0 igw-xxxxx Internet access

Associated Subnets: 10.0.1.0/24, 10.0.2.0/24

Private Route Table (AZ-1)

Destination Target Purpose
10.0.0.0/16 local VPC internal traffic
0.0.0.0/0 eni-xxxxx (NAT Instance) Internet via NAT
pl-xxxxx (S3) vpce-xxxxx S3 via endpoint
pl-xxxxx (DynamoDB) vpce-xxxxx DynamoDB via endpoint

Associated Subnets: 10.0.11.0/24

Private Route Table (AZ-2)

Destination Target Purpose
10.0.0.0/16 local VPC internal traffic
0.0.0.0/0 eni-xxxxx (NAT Instance) Internet via NAT
pl-xxxxx (S3) vpce-xxxxx S3 via endpoint
pl-xxxxx (DynamoDB) vpce-xxxxx DynamoDB via endpoint

Associated Subnets: 10.0.12.0/24

Database Route Table

Destination Target Purpose
10.0.0.0/16 local VPC internal traffic only

Associated Subnets: 10.0.20.0/24, 10.0.21.0/24


Security Groups

ALB Security Group (sg-alb)

Name: tradai-alb-sg
Description: Security group for Application Load Balancer

Inbound Rules:
  - Protocol: TCP
    Port: 443
    Source: 0.0.0.0/0
    Description: HTTPS from internet

  - Protocol: TCP
    Port: 80
    Source: 0.0.0.0/0
    Description: HTTP redirect to HTTPS

Outbound Rules:
  - Protocol: TCP
    Port: 8000-8002
    Destination: sg-ecs
    Description: To ECS services

  - Protocol: TCP
    Port: 5000
    Destination: sg-ecs
    Description: To MLflow service

ECS Security Group (sg-ecs)

Name: tradai-ecs-sg
Description: Security group for ECS tasks

Inbound Rules:
  - Protocol: TCP
    Port: 8000
    Source: sg-alb
    Description: Backend API from ALB

  - Protocol: TCP
    Port: 8002
    Source: sg-alb
    Description: Data Collection from ALB

  - Protocol: TCP
    Port: 8002
    Source: sg-lambda
    Description: Data Collection from Lambda

  - Protocol: TCP
    Port: 5000
    Source: sg-alb
    Description: MLflow from ALB

  - Protocol: TCP
    Port: 5000
    Source: sg-ecs (self)
    Description: MLflow from other ECS tasks

Outbound Rules:
  - Protocol: TCP
    Port: 443
    Destination: 0.0.0.0/0
    Description: HTTPS to AWS APIs (via NAT)

  - Protocol: TCP
    Port: 5432
    Destination: sg-rds
    Description: PostgreSQL to RDS

Lambda Security Group (sg-lambda)

Name: tradai-lambda-sg
Description: Security group for Lambda functions in VPC

Inbound Rules:
  (None - Lambda initiates connections)

Outbound Rules:
  - Protocol: TCP
    Port: 8002
    Destination: sg-ecs
    Description: To Data Collection Service

  - Protocol: TCP
    Port: 443
    Destination: 0.0.0.0/0
    Description: HTTPS to AWS APIs (via NAT)

RDS Security Group (sg-rds)

Name: tradai-rds-sg
Description: Security group for RDS PostgreSQL

Inbound Rules:
  - Protocol: TCP
    Port: 5432
    Source: sg-ecs
    Description: PostgreSQL from ECS tasks

Outbound Rules:
  (None - RDS does not initiate connections)

NAT Instance Security Group (sg-nat)

Name: tradai-nat-sg
Description: Security group for NAT Instance

Inbound Rules:
  - Protocol: TCP
    Port: 443
    Source: 10.0.11.0/24
    Description: HTTPS from private subnet AZ-1

  - Protocol: TCP
    Port: 443
    Source: 10.0.12.0/24
    Description: HTTPS from private subnet AZ-2

  - Protocol: TCP
    Port: 80
    Source: 10.0.11.0/24
    Description: HTTP from private subnet AZ-1

  - Protocol: TCP
    Port: 80
    Source: 10.0.12.0/24
    Description: HTTP from private subnet AZ-2

Outbound Rules:
  - Protocol: TCP
    Port: 443
    Destination: 0.0.0.0/0
    Description: HTTPS to internet

  - Protocol: TCP
    Port: 80
    Destination: 0.0.0.0/0
    Description: HTTP to internet

VPC Endpoint Security Group (sg-vpce)

Name: tradai-vpce-sg
Description: Security group for VPC Interface Endpoints

Inbound Rules:
  - Protocol: TCP
    Port: 443
    Source: 10.0.0.0/16
    Description: HTTPS from VPC

Outbound Rules:
  - Protocol: All
    Port: All
    Destination: 0.0.0.0/0
    Description: All outbound

Network ACLs (NACLs)

Public Subnet NACL

Name: tradai-public-nacl

Inbound Rules:
  - Rule: 100
    Protocol: TCP
    Port: 443
    Source: 0.0.0.0/0
    Action: ALLOW
    Description: HTTPS

  - Rule: 110
    Protocol: TCP
    Port: 80
    Source: 0.0.0.0/0
    Action: ALLOW
    Description: HTTP

  - Rule: 120
    Protocol: TCP
    Port: 1024-65535
    Source: 0.0.0.0/0
    Action: ALLOW
    Description: Ephemeral ports (return traffic)

  - Rule: *
    Protocol: All
    Port: All
    Source: 0.0.0.0/0
    Action: DENY
    Description: Deny all other

Outbound Rules:
  - Rule: 100
    Protocol: TCP
    Port: 443
    Destination: 0.0.0.0/0
    Action: ALLOW
    Description: HTTPS

  - Rule: 110
    Protocol: TCP
    Port: 80
    Destination: 0.0.0.0/0
    Action: ALLOW
    Description: HTTP

  - Rule: 120
    Protocol: TCP
    Port: 8000-8002
    Destination: 10.0.0.0/16
    Action: ALLOW
    Description: To ECS services

  - Rule: 130
    Protocol: TCP
    Port: 5000
    Destination: 10.0.0.0/16
    Action: ALLOW
    Description: To MLflow

  - Rule: 140
    Protocol: TCP
    Port: 1024-65535
    Destination: 0.0.0.0/0
    Action: ALLOW
    Description: Ephemeral ports

  - Rule: *
    Protocol: All
    Port: All
    Destination: 0.0.0.0/0
    Action: DENY

Private Subnet NACL

Name: tradai-private-nacl

Inbound Rules:
  - Rule: 100
    Protocol: TCP
    Port: 8000-8002
    Source: 10.0.1.0/24
    Action: ALLOW
    Description: From ALB AZ-1

  - Rule: 110
    Protocol: TCP
    Port: 8000-8002
    Source: 10.0.2.0/24
    Action: ALLOW
    Description: From ALB AZ-2

  - Rule: 120
    Protocol: TCP
    Port: 5000
    Source: 10.0.0.0/16
    Action: ALLOW
    Description: MLflow from VPC

  - Rule: 130
    Protocol: TCP
    Port: 1024-65535
    Source: 0.0.0.0/0
    Action: ALLOW
    Description: Ephemeral ports (return traffic from NAT)

  - Rule: *
    Protocol: All
    Port: All
    Source: 0.0.0.0/0
    Action: DENY

Outbound Rules:
  - Rule: 100
    Protocol: TCP
    Port: 443
    Destination: 0.0.0.0/0
    Action: ALLOW
    Description: HTTPS to internet (via NAT)

  - Rule: 110
    Protocol: TCP
    Port: 5432
    Destination: 10.0.20.0/24
    Action: ALLOW
    Description: PostgreSQL to RDS AZ-1

  - Rule: 120
    Protocol: TCP
    Port: 5432
    Destination: 10.0.21.0/24
    Action: ALLOW
    Description: PostgreSQL to RDS AZ-2

  - Rule: 130
    Protocol: TCP
    Port: 1024-65535
    Destination: 0.0.0.0/0
    Action: ALLOW
    Description: Ephemeral ports

  - Rule: *
    Protocol: All
    Port: All
    Destination: 0.0.0.0/0
    Action: DENY

Database Subnet NACL

Name: tradai-database-nacl

Inbound Rules:
  - Rule: 100
    Protocol: TCP
    Port: 5432
    Source: 10.0.11.0/24
    Action: ALLOW
    Description: PostgreSQL from private AZ-1

  - Rule: 110
    Protocol: TCP
    Port: 5432
    Source: 10.0.12.0/24
    Action: ALLOW
    Description: PostgreSQL from private AZ-2

  - Rule: *
    Protocol: All
    Port: All
    Source: 0.0.0.0/0
    Action: DENY

Outbound Rules:
  - Rule: 100
    Protocol: TCP
    Port: 1024-65535
    Destination: 10.0.11.0/24
    Action: ALLOW
    Description: Response to private AZ-1

  - Rule: 110
    Protocol: TCP
    Port: 1024-65535
    Destination: 10.0.12.0/24
    Action: ALLOW
    Description: Response to private AZ-2

  - Rule: *
    Protocol: All
    Port: All
    Destination: 0.0.0.0/0
    Action: DENY

NAT Instance Configuration

Why NAT Instance over NAT Gateway?

Aspect NAT Gateway NAT Instance
Cost $64.80/mo (2 AZs) $6.13/mo
Bandwidth 45 Gbps 5 Gbps
Availability Managed HA Self-managed
Maintenance Zero Patch OS
Savings - $58.67/mo

NAT Instance Specification

Instance Type: t4g.nano
AMI: Amazon Linux 2023 (arm64)
Key Pair: tradai-nat-key
Subnet: Public (10.0.1.0/24)
Security Group: sg-nat
Source/Dest Check: DISABLED  # Critical!

User Data:
  #!/bin/bash
  yum install iptables-services -y
  systemctl enable iptables
  systemctl start iptables

  # Enable IP forwarding
  echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf
  sysctl -p

  # Configure NAT
  iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
  iptables -F FORWARD
  service iptables save

Tags:
  Name: tradai-nat-instance
  Purpose: NAT for private subnets

Auto Scaling for HA

Auto Scaling Group:
  Name: tradai-nat-asg
  Min: 1
  Max: 1
  Desired: 1

  Health Check:
    Type: EC2
    Grace Period: 300 seconds

  Launch Template:
    Instance Type: t4g.nano
    AMI: ami-nat-configured
    Network: Public subnet

  Lifecycle Hook:
    # Update route tables on launch
    Lambda: update-nat-routes

Application Load Balancer

ALB Configuration

Name: tradai-alb
Scheme: internet-facing
Type: application
IP Address Type: ipv4

Subnets:
  - 10.0.1.0/24 (us-east-1a)
  - 10.0.2.0/24 (us-east-1b)

Security Groups:
  - sg-alb

Listeners:
  - Port: 443
    Protocol: HTTPS
    Certificate: arn:aws:acm:...:certificate/xxxxx
    Default Action: Forward to target group

  - Port: 80
    Protocol: HTTP
    Default Action: Redirect to HTTPS (301)

Access Logs:
  Enabled: true
  S3 Bucket: tradai-logs
  Prefix: alb/

Target Groups

Backend API Target Group:
  Name: tradai-backend-tg
  Protocol: HTTP
  Port: 8000
  Target Type: ip
  VPC: tradai-vpc

  Health Check:
    Path: /health
    Interval: 30 seconds
    Timeout: 5 seconds
    Healthy Threshold: 2
    Unhealthy Threshold: 3

Data Collection Target Group:
  Name: tradai-data-tg
  Protocol: HTTP
  Port: 8002
  Target Type: ip

  Health Check:
    Path: /health
    Interval: 30 seconds

MLflow Target Group:
  Name: tradai-mlflow-tg
  Protocol: HTTP
  Port: 5000
  Target Type: ip

  Health Check:
    Path: /health
    Interval: 30 seconds

Listener Rules

HTTPS Listener Rules:
  - Priority: 1
    Conditions:
      - Path: /strategies/*
      - Path: /data/*
      - Path: /health
      - Path: /backtest/*
    Action: Forward to tradai-backend-tg

  - Priority: 2
    Conditions:
      - Path: /mlflow/*
    Action: Forward to tradai-mlflow-tg

  - Priority: 100 (Default)
    Action: Fixed Response (404)

VPC Endpoints

Gateway Endpoints (Free)

S3 Gateway Endpoint:
  Service: com.amazonaws.us-east-1.s3
  Type: Gateway
  Route Tables:
    - rtb-private-az1
    - rtb-private-az2
  Policy: Full access to tradai-* buckets

DynamoDB Gateway Endpoint:
  Service: com.amazonaws.us-east-1.dynamodb
  Type: Gateway
  Route Tables:
    - rtb-private-az1
    - rtb-private-az2
  Policy: Full access to tradai-* tables

Interface Endpoints (Optional)

Recommendation: Skip interface endpoints and use NAT Instance to save $28/month.

If needed for high-security environments:

ECR API Endpoint:
  Service: com.amazonaws.us-east-1.ecr.api
  Type: Interface
  Subnets: Private subnets
  Security Group: sg-vpce
  Private DNS: Enabled

ECR DKR Endpoint:
  Service: com.amazonaws.us-east-1.ecr.dkr
  Type: Interface
  Subnets: Private subnets
  Security Group: sg-vpce
  Private DNS: Enabled

Secrets Manager Endpoint:
  Service: com.amazonaws.us-east-1.secretsmanager
  Type: Interface
  Subnets: Private subnets
  Security Group: sg-vpce
  Private DNS: Enabled

VPC Flow Logs

Flow Log Configuration:
  Name: tradai-vpc-flow-logs
  Resource: VPC
  Traffic Type: ALL

  Destination: CloudWatch Logs
  Log Group: /aws/vpc/tradai-flow-logs
  Retention: 7 days

  IAM Role: tradai-flow-logs-role

  Log Format: (default)

  Filter Pattern: (optional)
    # Alert on rejected traffic
    [version, account_id, interface_id, srcaddr, dstaddr,
     srcport, dstport, protocol, packets, bytes, start, end,
     action="REJECT", log_status]

DNS Configuration

Private Hosted Zone

Hosted Zone:
  Name: tradai.local
  Type: Private
  VPC: tradai-vpc

Records:
  - Name: backend.tradai.local
    Type: A
    Alias: ALB DNS name

  - Name: data.tradai.local
    Type: A
    Alias: ALB DNS name

  - Name: mlflow.tradai.local
    Type: A
    Alias: ALB DNS name

  - Name: db.tradai.local
    Type: CNAME
    Value: RDS endpoint

Cost Summary

Component Configuration Monthly Cost
NAT Instance t4g.nano $6.13
ALB 1 LB, minimal traffic $17.00
S3 Gateway Endpoint Free $0.00
DynamoDB Gateway Endpoint Free $0.00
VPC Flow Logs 7 days retention $2.00
TOTAL $25.13

Savings vs NAT Gateway: $58.67/month (90% reduction)


Network Validation Checklist

  • [x] VPC created with 10.0.0.0/16 CIDR
  • [x] 6 subnets across 2 AZs (public, private, database)
  • [x] Internet Gateway attached
  • [x] NAT Instance in public subnet
  • [x] Route tables configured correctly
  • [x] Security groups with least privilege
  • [x] NACLs for defense in depth
  • [x] Database subnets isolated (no internet)
  • [x] VPC Flow Logs enabled
  • [x] Gateway endpoints for S3 and DynamoDB
  • [x] ALB in public subnets
  • [x] ECS tasks in private subnets
  • [x] RDS in database subnets

Next Steps

  1. Review 04-SECURITY.md for security controls
  2. Review 09-PULUMI-CODE.md for implementation