Skip to content

Networking

VPC

Property Value
Name prod-nhc
CIDR 10.1.0.0/16
Region us-east-2
AZs us-east-2a, us-east-2b
DNS Hostnames Enabled
DNS Resolution Enabled

Subnets

Subnet CIDR AZ Type
prod-nhc-public-0 10.1.0.0/24 us-east-2a Public
prod-nhc-public-1 10.1.1.0/24 us-east-2b Public
prod-nhc-private-0 10.1.10.0/24 us-east-2a Private
prod-nhc-private-1 10.1.11.0/24 us-east-2b Private

Internet Gateway & NAT

  • Internet Gateway — attached to VPC, routes 0.0.0.0/0 traffic from public subnets
  • NAT Gateway — in public subnet, provides outbound internet access for private subnets (EC2 instances pull Docker images, apt packages, etc.)

Security Groups

Each EC2 instance and service gets its own security group created by the respective OpenTofu module. The principle of least privilege is enforced — only the required ports from specific source security groups are allowed.

Security Group Allows Inbound Source
prod-nhc-django-sg 3000 (Portal), 8000 (Django API) ALB Django SG
prod-nhc-app-sg 80 (WordPress), 3006 (Gatsby) ALB WordPress SG
prod-nhc-foursites-sg 3001-3004 (4 sites) ALB Foursites SG
prod-nhc-gitlab-runner-sg (no inbound)
prod-nhc-django-rds-sg 3306 (MySQL) Django EC2 SG
prod-nhc-wpcms-rds-sg 3306 (MariaDB) App EC2 SG
prod-nhc-django-redis-sg 6379 (Redis) Django EC2 SG

Network Diagram

graph TB
    IGW[Internet Gateway] --> PUB1["Public 10.1.0.0/24<br/>AZ: us-east-2a"]
    IGW --> PUB2["Public 10.1.1.0/24<br/>AZ: us-east-2b"]
    PUB1 --> NAT[NAT Gateway]
    NAT --> PRIV1["Private 10.1.10.0/24<br/>AZ: us-east-2a"]
    NAT --> PRIV2["Private 10.1.11.0/24<br/>AZ: us-east-2b"]

OpenTofu Reference

The VPC is managed by the vpc module:

module "vpc" {
  source               = "../../modules/vpc"
  name                 = "prod-nhc"
  region               = "us-east-2"
  vpc_cidr             = "10.1.0.0/16"
  public_subnet_cidrs  = ["10.1.0.0/24", "10.1.1.0/24"]
  private_subnet_cidrs = ["10.1.10.0/24", "10.1.11.0/24"]
  availability_zones   = ["us-east-2a", "us-east-2b"]
}