Security in this stack is built on a defense-in-depth model: rather than relying on a single perimeter, three separate security groups enforce the principle of least privilege at every tier. The ALB security group accepts public web traffic, the Node security group accepts traffic only from the ALB, and the MongoDB security group accepts database connections only from the Node security group. No direct path from the internet to MongoDB exists at the network layer. On top of that, every EC2 instance is hardened with IMDSv2 enforcement, encrypted EBS volumes, and an IAM role that enables AWS Systems Manager access without opening SSH to the world.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.
Security Group Architecture
ALB Security Group
The ALB security group is the only one with inbound rules sourced from0.0.0.0/0, making it the sole public-facing entry point into the stack.
| Direction | Protocol | Port | Source | Description |
|---|---|---|---|---|
| Inbound | TCP | 80 | 0.0.0.0/0 | HTTP from internet |
| Inbound | TCP | 443 | 0.0.0.0/0 | HTTPS from internet |
| Outbound | All | All | 0.0.0.0/0 | All outbound traffic |
<project_name>-alb-sg
Node.js Security Group
The Node security group restricts HTTP traffic to originate only from the ALB security group ID (not a CIDR block). This means even if an IP address somehow matched the ALB’s IP, it would be rejected unless it is traffic actually forwarded by the ALB itself.| Direction | Protocol | Port | Source | Description |
|---|---|---|---|---|
| Inbound | TCP | 80 | ALB Security Group | HTTP forwarded from ALB |
| Inbound | TCP | 22 | var.allowed_ssh_ip | SSH from operator IP |
| Outbound | All | All | 0.0.0.0/0 | All outbound traffic |
<project_name>-node-sg
MongoDB Security Group
The MongoDB security group has no inbound rules sourced from any CIDR. Port 27017 is open exclusively to the Node.js security group, so MongoDB is unreachable from the internet, from the public subnets, or from any other resource in the VPC that does not carry the Node security group.| Direction | Protocol | Port | Source | Description |
|---|---|---|---|---|
| Inbound | TCP | 27017 | Node Security Group | MongoDB from Node.js tier only |
| Outbound | All | All | 0.0.0.0/0 | All outbound traffic |
<project_name>-mongo-sg
MongoDB is never assigned a public IP address (
associate_public_ip_address = false
in modules/ec2-instance/main.tf). Combined with its private subnet placement
and the security group restriction above, this provides three independent
layers preventing direct internet access to the database.EC2 Instance Hardening
Every EC2 instance in the stack — regardless of tier — is provisioned with the same hardening baseline defined in theec2-instance module.
IMDSv2 Enforced
http_tokens = "required" forces all requests to the EC2 Instance Metadata
Service to use session-oriented tokens. This prevents SSRF vulnerabilities
from being used to harvest IAM credentials or other sensitive metadata via
unauthenticated GET requests to 169.254.169.254.Encrypted gp3 EBS Volumes
Root block devices use the
gp3 volume type with encrypted = true and a
default size of 20 GB. Encryption is applied at rest using AWS-managed keys,
protecting data if a volume snapshot is ever exposed.User Data Replace on Change
user_data_replace_on_change = true ensures that whenever the user-data
script is modified, Terraform destroys and recreates the instance rather
than leaving a running instance with stale bootstrap configuration.metadata_options and root_block_device blocks from modules/ec2-instance/main.tf:
IAM Role and Instance Profile
An IAM role named<project_name>-ec2-role is created and attached to every EC2 instance through an instance profile. The only managed policy attached is AmazonSSMManagedInstanceCore, which grants the minimum permissions needed for AWS Systems Manager Session Manager.
| Resource | Name |
|---|---|
| IAM Role | <project_name>-ec2-role |
| Managed Policy | arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore |
| Instance Profile | <project_name>-instance-profile |
AmazonSSMManagedInstanceCore policy and IMDSv2 enabled, operators can open an interactive shell session via the AWS Console or aws ssm start-session CLI command without any inbound security group rule for SSH. This eliminates the need to manage SSH key distribution for day-to-day operations and removes port 22 as an attack surface entirely.
Node Security Group HCL
The following is the exact Terraform declaration for the Node.js security group, taken frommodules/security/main.tf: