Architecture proven by code.
A candid, repository-backed account of how AWS networking, ingress, compute, storage, identity, DNS, and environment sharing are managed with Terraform—and where the current design should evolve.
AWS Infrastructure
Explore the sanitized multi-zone architecture with nested AWS Region, VPC, subnet, and availability-zone boundaries. Exact CIDRs, ports, instance details, and resource identifiers are intentionally excluded.
Why the system is shaped this way
Stable ingress, explicit routing
Route 53 aliases converge on one HTTPS ALB. Host rules send the website, API, admin, and Grafana to dedicated instance target groups, while health checks remove unhealthy targets from routing.
Application ports behind the ALB
Website, API, and admin security groups use ALB security-group references for application ingress. SSH is separately CIDR-scoped. This is stronger than open application ports, but the public-subnet placement and public IPs remain real attack-surface debt.
Separate compute and state
Each application surface runs on its own encrypted EC2 volume. S3 holds persistent assets and the API receives access through an IAM instance profile, so AWS credentials do not need to be embedded in containers.
Reuse with acknowledged coupling
Staging creates independent instances and routing rules but looks up the production VPC, subnet, security groups, ALB, and listener. This lowers cost while coupling environment availability and change coordination.
Reviewable changes, repeatable reconciliation.
Terraform turns infrastructure changes into a Git diff and a plan before AWS is changed. In this repository, production also records previously existing infrastructure as managed resources, while staging composes on top of shared foundations through data lookups.
terraform/
├── environments/
│ ├── prod/ # imported production VPC, EC2, ALB + DNS, S3, IAM
│ └── staging/ # shared-foundation lookups + staging compute/routing
└── modules/
├── networking/ # reusable VPC/public/private/NAT design (not invoked by current envs)
├── security/
├── alb/
├── compute/ec2/
└── s3/terraform init
terraform fmt -check
terraform validate
terraform plan
terraform apply # manually controlled; no Terraform CI apply is evidencedIngress is chained by intent.
The ALB is public on HTTP/HTTPS. Application ports are allowed by source security group instead of global CIDRs. Administrative SSH is still a public, IP-allowlisted path and should move toward SSM-only access.
Internet (80/443)
↓
ALB security group
├── SG reference → Website :3000
├── SG reference → API :8080
└── SG reference → Admin :3000
Developer CIDR → SSH :22 (website, API, admin)What the current design buys—and costs.
Dedicated EC2 hosts
Benefit: simple workload separation and direct operational control.
Cost: manual host capacity, patching, single-instance failure domains, and public-addressed compute.
Shared ALB and network
Benefit: lower staging cost and centralized TLS/host routing.
Cost: listener priorities, security groups, and foundational changes are coupled across environments.
Imported production resources
Benefit: existing AWS infrastructure becomes visible and reviewable in Terraform.
Cost: lifecycle ignore rules can mask console drift and weaken convergence.
Next changes, ordered by the problem they solve.
- Move workloads to private subnets and use SSM-only management.
Removes public instance addresses and SSH ingress while preserving controlled operations.
- Add redundant compute across Availability Zones.
The ALB is multi-AZ, but each application is currently a single EC2 target in one zone.
- Separate staging state and network boundaries.
Reduces blast radius when isolation matters more than the cost of shared foundations.
- Add a plan/approval/apply pipeline and remote-state evidence.
The repository shows provider configuration but no remote backend or automated Terraform delivery; a reviewed pipeline would improve traceability and state safety.