This repository contains Infrastructure as Code (IaC) using Terraform to deploy a containerized application (Node.JS) on AWS Elastic Container Service (ECS) with EC2 launch type. The infrastructure is designed with high availability, scalability, and security best practices in mind.
The infrastructure includes the following:
-
Networking Layer:
- VPC with CIDR
10.0.0.0/16
- 2 Public Subnets across different AZs
- 2 Private Subnets across different AZs
- NAT Gateways for private subnet internet access
- Internet Gateway for public subnet access
- VPC with CIDR
-
Compute Layer:
- ECS Cluster with EC2 launch type
- Auto Scaling Group for EC2 instances
- Application Load Balancer for traffic distribution
- ECS Tasks running containerized applications
-
Data Layer:
- DynamoDB Tables for User, Product, and Order management
-
Monitoring, Security & Others:
- Amazon CloudWatch for monitoring and logging
- IAM roles and policies for secure access management
- Security Groups for network access control
- ECR Repository that contains the docker image
- AWS Account with administrative access or required permission
- Terraform (>= 1.0.0)
- AWS CLI configured with appropriate credentials
- Docker for container image building
- Clone the repository:
git clone https://github.com/sagar-uprety/ecs-on-ec2-terraform.git
cd ecs-on-ec2-terraform
- You need an S3 bucket as a backend for Terraform state. Create one if you have not already and update the backend configuration in
versions.tf
:
...
backend "s3" {
bucket = "dev-terraform-state-bucket" # update the bucket name here
region = "us-east-2"
encrypt = true
key = "main/terraform.tfstate"
}
...
- Initialize Terraform:
terraform init
- Configure your deployment:
# Edit dev.tfvars with your configuration
- Review the deployment plan:
terraform plan --var-file="dev.tfvars"
- Apply the infrastructure:
terraform apply --var-file="dev.tfvars"
- Cleanup the infrastructure (Caution: If you do not destroy the resources, cost might incure):
terraform destroy --var-file="dev.tfvars"
.
├── README.md
├── main.tf # Main Terraform configuration
├── variables.tf # Input variables declaration
├── outputs.tf # Output values configuration
├── providers.tf # Provider configuration
├── versions.tf # Terraform version constraints and backend configuration
├── dev.tfvars # Development environment variables
└── .gitignore # Git ignore rules
main.tf
: Defines the core infrastructure for ecs_cluster, ecs_service, and supporting resourcesvariables.tf
: Input variables for parameterization and sensitive dataprovider.tf
: Specifies the AWS provideroutput.tf
: Defines outputs for the tf configsdev.tfvars
: Variables specific to the dev environmentversions.tf
: Terraform version constraints and backend configurationlocals.tf
: local value to be used in main.tf.pre-commit-config.yaml
: git pre-commit configuration.gitignore
: Lists files to exclude from version control
Variable Name | Description | Type | Default |
---|---|---|---|
environment |
Environment name | string | `` |
application |
Application name | string | `` |
owner |
Resource owner | string | `` |
region |
AWS region to deploy resources | string | `` |
Refer to variables.tf
for a complete list of optional variables and their default values.
- All EC2 instances are deployed in private subnets
- Security groups follow the principle of least privilege
- IAM roles are scoped to minimum required permissions
The deployment includes:
- CloudWatch metrics for ECS services and tasks
- Container insights for performance monitoring
- ALB access logs (stored in S3)
- ECS task logs in CloudWatch Logs
The sample e-commerce application (Node.js) with source code and dockerfile can be found here
- Fork the repository
- Create your feature branch (
git checkout -b feature/AmazingFeature
) - Commit your changes (
git commit -m 'Add some AmazingFeature'
) - Push to the branch (
git push origin feature/AmazingFeature
) - Open a Pull Request
This project is licensed under the MIT License - see the LICENSE file for details.