Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/mcamacho97/terraform-mean-stack-aws/llms.txt

Use this file to discover all available pages before exploring further.

This project deploys a production-grade MEAN stack on AWS using a classic three-tier architecture: a web tier handled by an Application Load Balancer, an application tier comprised of two Ubuntu EC2 instances running Node.js behind Nginx, and a data tier consisting of a MongoDB server isolated in a private subnet. Every resource is provisioned through Terraform modules, enabling repeatable, version-controlled infrastructure that can be torn down and recreated with a single command.

Architecture Diagram

                Internet

          Application Load Balancer

      ┌─────────────┴─────────────┐
      │                           │
  EC2 Node 1                 EC2 Node 2
Ubuntu + Node.js + Nginx   Ubuntu + Node.js + Nginx
      │                           │
      └─────────────┬─────────────┘

           EC2 MongoDB (Private)

              NAT Gateway

            Internet Gateway

Component Breakdown

Application Load Balancer

Internet-facing ALB spanning both public subnets. Listens on HTTP port 80, forwards traffic to a target group containing both Node.js instances, and runs health checks against the /health endpoint every 30 seconds.

Node.js App Servers (×2)

Two Ubuntu 24.04 LTS EC2 instances — one per Availability Zone — each running Node.js 22 with an Express application on port 3000 and Nginx as a reverse proxy on port 80. Deployed via automated user-data scripts.

MongoDB Server

A single EC2 instance in the private subnet running MongoDB 8.0. It has no public IP address and is reachable only from the Node.js security group on port 27017, preventing any direct internet exposure.

VPC & Subnets

A dedicated VPC (default CIDR 10.0.0.0/16) with two public subnets across separate Availability Zones for the app tier, and one private subnet for the database tier. All CIDRs are configurable via Terraform variables.

NAT Gateway

Deployed in the first public subnet with an Elastic IP. Allows the MongoDB instance in the private subnet to initiate outbound connections — such as OS updates and package installs — without being reachable from the internet.

IAM & Security

Three layered security groups (ALB, Node, MongoDB) enforce least-privilege network access. An IAM role with AmazonSSMManagedInstanceCore is attached to every EC2 instance, enabling Systems Manager Session Manager without requiring open SSH ports.

Traffic Flow

Requests travel through clearly defined layers from the public internet to the database:
1

Internet → ALB

A client sends an HTTP request to the ALB’s public DNS name on port 80. The ALB listener forwards the request to the terraform-mean-tg target group.
2

ALB → Node.js Instances

The target group load-balances across Node 1 and Node 2 at port 80. Each Node instance runs Nginx, which acts as a reverse proxy and forwards the request internally to the Express application on port 3000.
3

Node.js → MongoDB

The Express application connects to the MongoDB server using its private IP address on port 27017. Because MongoDB sits in a private subnet with no public IP, this connection never traverses the public internet.

High Availability

The application tier is distributed across two separate AWS Availability Zones (by default us-east-1a and us-east-1b), so a single AZ failure leaves the remaining Node.js instance fully operational. The ALB continuously evaluates instance health using the following configuration:
ParameterValue
Health check pathGET /health
Expected status code200
Check interval30 seconds
Timeout5 seconds
Healthy threshold2 consecutive hits
Unhealthy threshold2 consecutive hits
When an instance fails two consecutive health checks, the ALB stops routing traffic to it automatically. Once the instance recovers and passes two checks, it is reinstated into rotation without any manual intervention.

Data Flow

The Node.js application connects to MongoDB exclusively over the private subnet. The MongoDB security group permits inbound traffic on port 27017 only from the Node.js security group ID — not from any CIDR block — meaning even other resources inside the VPC cannot reach MongoDB unless they carry the Node security group. Outbound traffic from MongoDB flows through the NAT Gateway for package management and OS updates, but no inbound path from the internet exists.
All three EC2 instances are provisioned with encrypted gp3 root volumes (20 GB default) and IMDSv2 enforced, ensuring instance metadata cannot be accessed without a session-oriented token.

Networking

VPC layout, subnet CIDRs, Internet Gateway, NAT Gateway, and route table configuration in detail.

Security

Security group rules, IMDSv2 enforcement, EBS encryption, and IAM role configuration for every tier.

Build docs developers (and LLMs) love