This project demonstrates how to deploy a containerized web application to AWS using Amazon ECS (Elastic Container Service) with Fargate, Amazon ECR (Elastic Container Registry), and Amazon CloudFront.
The application uses the following AWS services and components:
- Amazon ECR: Stores the Docker container image
- Amazon ECS with Fargate: Runs the containerized application without managing servers
- Application Load Balancer: Distributes traffic to the ECS tasks
- Amazon CloudFront: Provides global content delivery and HTTPS termination
- Amazon S3: Stores CloudFront access logs
- Amazon CloudWatch: Monitors and alerts on application metrics
- Amazon SNS: Sends notifications for alarms
- VPC with public subnets: Provides the networking infrastructure
- IAM Roles: Grants necessary permissions for ECS task execution
+-------------+
| |
| Users |
| |
+------+------+
|
| HTTPS
v
+-------------+
| |
| CloudFront |
| |
+------+------+
|
| HTTP
v
+-------------+
| |
| ALB |
| |
+------+------+
|
| Route Traffic
v
+------------------+ +---------------+
| | | |
| ECR Repository +----------->| ECS Cluster |
| | Pull | |
+------------------+ Images +-------+-------+
|
| Manage
+----------------+-----------------+
| |
+-------+-------+ +-------+-------+
| | | |
| ECS Task 1 | | ECS Task 2 |
| (Fargate) | | (Fargate) |
| | | |
+---------------+ +---------------+
+------------------+ +------------------+ +------------------+
| | | | | |
| CloudWatch |<-----------+ CloudFront +----------->| S3 |
| Monitoring | Metrics | | Logs | Logging |
| | | | | |
+--------+---------+ +------------------+ +------------------+
|
| Alarms
v
+------------------+
| |
| SNS |
| Notifications |
| |
+------------------+
.
├── docker/
│ ├── Dockerfile # NGINX container configuration
│ └── index.html # Simple web page to serve
├── modules/
│ ├── vpc/ # VPC infrastructure module
│ ├── ecr/ # ECR repository module
│ ├── ecs/ # ECS cluster and service module
│ ├── alb/ # Application Load Balancer module
│ ├── cf/ # CloudFront distribution module
│ ├── s3/ # S3 bucket for logs module
│ ├── sns/ # SNS notifications module
│ └── cw/ # CloudWatch monitoring module
├── main.tf # Main Terraform configuration
├── variables.tf # Terraform variables
├── outputs.tf # Terraform outputs
├── ecr_push.sh # Script to build and push Docker image to ECR
└── README.md # This file
- AWS CLI configured with appropriate credentials
- Terraform installed
- Docker installed
- Existing ECR repository
terraform init
terraform fmt
If you don't have an image in ECR yet: If you haven’t pushed your app image to ECR yet, Check for ecr_push.sh in scripts folder and run the commands. This script will:
- Build the Docker image from the Dockerfile in the docker directory
- Tag the image with the ECR repository URL
- Push the image to the ECR repository
If you already have an image in ECR: You can skip this step and proceed to the next one.
Ensure the following are correctly defined and populated:
In variables.tf:
- Region
- ECR repo name
- S3 log bucket name (optional default or dynamic name)
- CloudFront price class or alias config (if any)
- email for SNS Topic Subscription
- Restrict access to specific IP addresses for security (Check in VPC module main.tf)
- ECS Tasks memory,CPU and number of tasks
- log retention period
terraform plan -out=tfplan
terraform apply tfplan
Or simply:
terraform apply
After deployment is complete, you can access the application using the CloudFront domain name, which is available in the Terraform outputs:
terraform output
You can also access the application directly via the ALB:
terraform output load_balancer_dns
or you can already have a outputs.txt file in local (Thanks to null_resources block in the main.tf)
The infrastructure includes CloudWatch monitoring and logging for the CloudFront distribution:
- CloudWatch Log Group: Captures CloudFront logs with a 30-day retention period
- CloudWatch Alarms: Monitors for 403 and 5xx error rates, triggering when they exceed thresholds
- CloudWatch Dashboard: Provides visualization of CloudFront metrics including requests and error rates
- S3 Bucket: Stores CloudFront access logs with lifecycle policies
- SNS Topic: Sends notifications when alarms are triggered
To access the CloudWatch Dashboard:
aws cloudwatch get-dashboard --dashboard-name $(terraform output -raw cloudwatch_dashboard)
To avoid incurring charges, destroy the resources when you're done:
terraform destroy
Note about ECR Repository: The ECR repository is referenced as a data source and not managed by Terraform. If you need to delete the repository and all its images, you'll need to:
- Uncomment and modify the
aws_ecr_repository
resource in the ECR module - Set
force_delete = true
in the resource configuration - Update the data source to reference this resource instead
- Run
terraform apply
followed byterraform destroy
WARNING: Using force_delete = true
will delete all images in the repository when destroyed.
- The application is deployed in public subnets with a public load balancer for demonstration purposes
- CloudFront provides HTTPS using its default certificate
- CloudWatch alarms monitor for suspicious error patterns
- In a production environment, consider using private subnets for the ECS tasks and implementing additional security measures
- The security group allows inbound traffic on ports 80 and 443
- Modify the
docker/index.html
file to change the web content - Update the module configurations in
main.tf
to adjust the infrastructure - Edit the task definition in the ECS module to change container specifications
- Adjust CloudWatch alarm thresholds in the CW module
- Add additional email addresses to the SNS notifications
This project uses Terraform null resources for several important tasks:
A null resource in the main configuration collects all important infrastructure outputs into a single text file:
resource "null_resource" "outputs" {
triggers = {
always_run = "${timestamp()}"
}
provisioner "local-exec" {
command = <<-EOT
echo "VPC ID: ${module.vpc.vpc_id}" > outputs.txt
echo "ECR Repository URL: ${module.ecr.repository_url}" >> outputs.txt
# Additional outputs...
EOT
}
}
For more information about Terraform null resources and their uses in DevOps automation, refer to: Terraform null_resource: Your Secret Weapon for DevOps Automation
Creates the networking infrastructure including VPC, subnets, route tables, and security groups.
References an existing ECR repository.
Creates the Application Load Balancer, target group, and HTTP listener.
Creates a CloudFront distribution with the ALB as its origin, providing global content delivery and HTTPS.
Creates an S3 bucket for storing CloudFront access logs with lifecycle policies.
Creates an SNS topic for alarm notifications with email subscriptions.
Creates CloudWatch alarms, log groups, and dashboards for monitoring CloudFront metrics.
Creates the ECS cluster, task definition, and service that runs the containerized application.