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 guide walks you through every step required to go from zero to a fully running, highly available MEAN stack on AWS. By the end you will have two Node.js application servers behind an Application Load Balancer and a private MongoDB instance — all provisioned automatically by Terraform.
1

Prerequisites Check

Before you begin, confirm you have the following tools installed and configured.Terraform >= 1.12
terraform -version
The output must show Terraform v1.12.0 or higher. Download the latest version from developer.hashicorp.com/terraform/downloads if needed.AWS CLI — configured with credentials
aws sts get-caller-identity
A successful response returns your UserId, Account, and Arn. If it fails, run aws configure and supply your AWS Access Key ID, AWS Secret Access Key, and default region.S3 Bucket for Terraform BackendYou need an existing S3 bucket to store Terraform remote state. Create one if you don’t already have one:
aws s3api create-bucket \
  --bucket my-terraform-state-bucket \
  --region us-east-1
S3 bucket names are globally unique. Replace my-terraform-state-bucket with a name that is unique to your AWS account.
2

Clone the Repository

Clone the project and change into its directory:
git clone https://github.com/mcamacho97/terraform-mean-stack-aws.git && cd terraform-mean-stack-aws
3

Create backend.hcl

The backend.tf file contains an empty s3 backend block that is populated at terraform init time via a separate configuration file. Create backend.hcl in the project root with your S3 bucket details:
bucket  = "my-terraform-state-bucket"
key     = "terraform-mean/terraform.tfstate"
region  = "us-east-1"
encrypt = true
backend.hcl contains environment-specific values and should not be committed to source control. Add it to your .gitignore.
4

Create terraform.tfvars

Copy the provided example file and customise it with your own values:
cp terraform.tfvars.example terraform.tfvars
The full set of required variables is shown below. Open terraform.tfvars in your editor and update the values as needed:
project_name         = "terraform-mean"
environment          = "lab"
aws_region           = "us-east-1"

vpc_cidr             = "10.0.0.0/16"
public_subnet_1_cidr = "10.0.1.0/24"
public_subnet_2_cidr = "10.0.2.0/24"
private_subnet_cidr  = "10.0.3.0/24"

availability_zone_1  = "us-east-1a"
availability_zone_2  = "us-east-1b"

instance_type        = "t2.micro"
node_instance_count  = 2

allowed_ssh_ip       = "YOUR_PUBLIC_IP/32"
The allowed_ssh_ip variable restricts SSH access to a single IP. Get your current public IP by running:
curl ifconfig.me
Replace YOUR_PUBLIC_IP/32 with the returned address, for example 203.0.113.42/32.
5

Initialize Terraform

Initialize the working directory, download required providers, and configure the S3 backend in one command:
terraform init -backend-config=backend.hcl
A successful run ends with:
Terraform has been successfully initialized!
6

Validate the Configuration

Check that all Terraform files are syntactically correct and internally consistent:
terraform validate
Expected output:
Success! The configuration is valid.
7

Review the Plan

Preview every resource Terraform will create before touching your AWS account:
terraform plan
Review the output carefully. You should see resources being created across the network, security, keypair, iam, ec2-instance (×3), and alb modules — approximately 25–30 resources in total.
Save the plan to a file with terraform plan -out=tfplan and then apply that exact plan with terraform apply tfplan to avoid any drift between plan and apply.
8

Apply the Configuration

Deploy all infrastructure to AWS:
terraform apply
Terraform will display the execution plan one final time and prompt for confirmation. Type yes to proceed.
A full deployment typically takes 3–5 minutes. The majority of this time is EC2 instance launch and user-data script execution (Node.js, Nginx, and MongoDB installation).
Running this command provisions real AWS resources that will incur costs. Remember to run terraform destroy when you are finished to tear everything down.
9

Access Your Application

Once terraform apply completes, retrieve the ALB DNS name from the Terraform outputs:
terraform output alb_dns_name
Copy the returned DNS name and open it in your browser:
http://<alb_dns_name>
The ALB routes requests to one of the two Node.js + Nginx application nodes. If you see your Express application’s response, the deployment was successful.
It may take an additional 1–2 minutes after terraform apply finishes for the user-data scripts to complete and the ALB health checks to report the targets as healthy.

What Was Deployed

After a successful terraform apply, the following outputs are available:
terraform output
OutputDescription
vpc_idID of the provisioned VPC
node_1_public_ipPublic IP address of the first Node.js application server (AZ 1)
node_1_private_ipPrivate IP address of the first Node.js application server (AZ 1)
node_2_public_ipPublic IP address of the second Node.js application server (AZ 2)
node_2_private_ipPrivate IP address of the second Node.js application server (AZ 2)
mongodb_private_ipPrivate IP of the MongoDB instance (accessible from app nodes only)
alb_dns_nameDNS name of the Application Load Balancer — use this as your app URL
nat_gateway_public_ipElastic IP assigned to the NAT Gateway (outbound traffic from private subnet)
private_key_pathLocal path to the auto-generated SSH private key file
You can query any individual output by name:
# ALB DNS name
terraform output alb_dns_name

# Node public and private IPs
terraform output node_1_public_ip
terraform output node_1_private_ip
terraform output node_2_public_ip
terraform output node_2_private_ip

# MongoDB private IP
terraform output mongodb_private_ip

# SSH key path
terraform output private_key_path

SSH Access

The SSH private key is automatically generated by Terraform and saved locally at keys/<project_name>.pem (for example, keys/terraform-mean.pem). Set the correct permissions before using it:
chmod 400 keys/terraform-mean.pem
ssh -i keys/terraform-mean.pem ubuntu@<node_1_public_ip>

Tear Down

When you are done, destroy all provisioned resources to avoid ongoing AWS charges:
terraform destroy
Type yes at the confirmation prompt. Terraform will remove every resource it created in reverse dependency order.
Now that your infrastructure is running, explore the Architecture Overview to understand how the modules are wired together and how to extend the project for production workloads.View Architecture Overview →

Build docs developers (and LLMs) love