NGINX Reverse Proxy Setup with AWS CloudFormation and Terraform
In this post we set up an NGINX reverse proxy on AWS with an Auto Scaling Groups (ASG) and Route 53 for load balancing. The infrastructure is provisioned using AWS CloudFormation and Terraform.
Overview
The setup includes:
EC2 Instances provisioned within an ASG to ensure high availability and scalability.
NGINX to be installed on each instance to act as a reverse proxy.
Amazon Route 53 used to manage DNS and provide load balancing across the EC2 instances.
Health Checks to monitor instance health and route traffic only to healthy instances.
Prerequisites
Before you begin, ensure you have the following:
- AWS Account with access to EC2, Auto Scaling, and Route 53.
- Properly set up AWS CLI and Terraform on your local machine.
- An SSH key pair created in the AWS region you are deploying to.
Configuration Files
The project includes the following configuration files:
`nginx_cloudformation.yaml`: CloudFormation template to set up the infrastructure.
AWSTemplateFormatVersion: '2010-09-09'
Description: NGINX Reverse Proxy with Route 53 Load Balancing
Resources:
NginxLaunchTemplate:
Type: AWS::EC2::LaunchTemplate
Properties:
LaunchTemplateName: NginxProxyTemplate
LaunchTemplateData:
ImageId: ami-0abcdef1234567890
InstanceType: t2.micro
KeyName: your-key-pair
UserData:
Fn::Base64: !Sub |
#!/bin/bash
apt update -y
apt install nginx -y
echo "server {
listen 80;
location / {
proxy_pass http://localhost:3000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}" > /etc/nginx/sites-available/default
systemctl restart nginx
NginxASG:
Type: AWS::AutoScaling::AutoScalingGroup
Properties:
LaunchTemplate:
LaunchTemplateId: !Ref NginxLaunchTemplate
Version: !GetAtt NginxLaunchTemplate.LatestVersionNumber
MinSize: 1
MaxSize: 3
DesiredCapacity: 2
VPCZoneIdentifier:
- subnet-12345
HealthCheckGracePeriod: 300
HealthCheckType: EC2
Tags:
- Key: Name
Value: nginx-proxy
PropagateAtLaunch: true
HealthCheck:
Type: AWS::Route53::HealthCheck
Properties:
HealthCheckConfig:
Type: HTTP
IPAddress: !GetAtt NginxASG.Instances[0].PrivateIp
Port: 80
ResourcePath: "/health"
RequestInterval: 30
FailureThreshold: 3
DNSRecord:
Type: AWS::Route53::RecordSet
Properties:
HostedZoneId: ZONEID
Name: "example.com."
Type: A
TTL: 60
ResourceRecords:
- !GetAtt NginxASG.Instances[0].PublicIp
HealthCheckId: !Ref HealthCheck
`nginx_terraform.tf`: Terraform configuration file.
provider "aws" {
region = "us-east-1"
}
resource "aws_launch_template" "nginx" {
name_prefix = "nginx-proxy-template-"
image_id = "ami-0abcdef1234567890"
instance_type = "t2.micro"
key_name = "your-key-pair"
user_data = base64encode(<<EOF
#!/bin/bash
apt update -y
apt install nginx -y
cat <<EOT > /etc/nginx/sites-available/default
server {
listen 80;
location / {
proxy_pass http://localhost:3000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
systemctl restart nginx
EOT
EOF
)
}
resource "aws_autoscaling_group" "nginx" {
launch_template {
id = aws_launch_template.nginx.id
version = "$Latest"
}
min_size = 1
max_size = 3
desired_capacity = 2
vpc_zone_identifier = ["subnet-12345"]
}
resource "aws_route53_health_check" "nginx" {
type = "HTTP"
resource_path = "/health"
ip_address = aws_instance.nginx.private_ip
port = 80
failure_threshold = 3
request_interval = 30
}
resource "aws_route53_record" "nginx" {
zone_id = "ZONEID"
name = "example.com"
type = "A"
ttl
Deployment
CloudFormation
Launch Template Setup: Navigate to the AWS Management Console.
Create Stack: Go to the AWS CloudFormation service, and choose "Create Stack".
Upload Template: Select the `nginx_cloudformation.yaml` file and follow the prompts to create the stack.
Terraform
Initialize Terraform:
terraform init
terraform plan
terraform apply
Usage
After deployment, your NGINX reverse proxy setup will route traffic through Route 53 to distribute requests across multiple EC2 instances based on health checks.
Monitoring and Management
- Use **AWS CloudWatch** to monitor the health and performance of your EC2 instances.
- Check **Route 53** health check status to ensure traffic is only routed to healthy instances.
Troubleshooting
- If an EC2 instance fails to pass health checks consistently, check the NGINX logs at `/var/log/nginx/error.log` for more details.
- Ensure that the security groups and network ACLs allow HTTP traffic on port 80.