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"]
}