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 is a Terraform Infrastructure as Code (IaC) implementation that provisions a production-ready, highly available multi-tier MEAN stack on AWS. It covers the complete picture: from the network layer (VPC, subnets, gateways) through compute (EC2), load balancing (ALB), and application runtime (Node.js 22 + Express 5 + MongoDB 8.0 behind Nginx), all fully automated using Terraform modules and user-data provisioning scripts — with remote state stored securely in S3.

Architecture

Traffic flows from the public internet through an Application Load Balancer distributed across two Availability Zones. Each AZ hosts an EC2 instance running Ubuntu 24.04 LTS with Node.js, Express, and an Nginx reverse proxy. Both application nodes communicate with a MongoDB 8.0 instance isolated in a private subnet. That private instance reaches the internet for package installation and updates through a NAT Gateway.
                    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

Key Features

Modular Architecture

The codebase is split into focused Terraform modules — network, security, keypair, iam, ec2-instance, and alb — making each component independently reusable and testable.

High Availability Across 2 AZs

Application nodes are deployed in two separate Availability Zones (us-east-1a and us-east-1b by default), eliminating single points of failure at the compute layer.

ALB with Health Checks

An Application Load Balancer distributes HTTP traffic across both Node.js instances and continuously monitors their health, automatically routing around unhealthy targets.

Private MongoDB Subnet

The MongoDB server is placed in a private subnet with no public IP, accessible only from the application tier via a dedicated security group rule, minimising the database attack surface.

Automated Provisioning via User-Data

Shell scripts in the userdata/ directory bootstrap Node.js + Nginx on application nodes and install MongoDB on the database node automatically at first boot — zero manual setup required.

S3 Remote State

Terraform state is stored in an S3 backend configured via backend.hcl, enabling safe team collaboration, state locking, and disaster recovery without committing sensitive state to source control.

Technologies

LayerTechnologyVersion
IaCTerraform>= 1.12
Cloud ProviderAWS (Hashicorp Provider)~> 6.0
TLS Key GenerationHashicorp TLS Provider~> 4.0
OSUbuntu Server LTS24.04
RuntimeNode.js22
Web FrameworkExpress5
DatabaseMongoDB8.0
Reverse ProxyNginxlatest

AWS Resources Deployed

The following AWS resources are created by a single terraform apply:
ResourceCountNotes
VPC1Dedicated network with custom CIDR
Public Subnets2One per Availability Zone
Private Subnet1Hosts the MongoDB instance
Internet Gateway1Attached to the VPC
NAT Gateway1Enables outbound internet from private subnet
Application Load Balancer1HTTP listener across both public subnets
Security Groups3Separate groups for ALB, Node.js nodes, and MongoDB
EC2 Instances32 Node.js application servers + 1 MongoDB server
IAM Role & Instance Profile1Attached to all EC2 instances
SSH Key Pair1Auto-generated; private key saved locally to keys/

Project Structure

terraform-mean/

├── backend.tf              # S3 backend configuration block
├── provider.tf             # AWS provider settings
├── versions.tf             # Terraform & provider version constraints
├── variables.tf            # Input variable declarations
├── terraform.tfvars        # Variable values (not committed)
├── locals.tf               # Local value expressions
├── data.tf                 # Data sources (e.g., Ubuntu AMI lookup)
├── outputs.tf              # Output values after apply
├── main.tf                 # Root module — wires all child modules together

├── modules/
│   ├── network/            # VPC, subnets, IGW, NAT Gateway
│   ├── security/           # Security groups for ALB, nodes, MongoDB
│   ├── keypair/            # TLS key generation and local file save
│   ├── iam/                # IAM role and instance profile
│   ├── ec2-instance/       # Reusable EC2 instance module
│   └── alb/                # Application Load Balancer and target group

└── userdata/
    ├── node.sh             # Bootstraps Node.js 22, Express 5, and Nginx
    └── mongo.sh            # Bootstraps MongoDB 8.0

Get Started

Ready to deploy your MEAN stack on AWS?

Quickstart Guide

Clone the repository, configure your variables, and run terraform apply to have a fully running MEAN stack infrastructure on AWS in under five minutes.

Build docs developers (and LLMs) love