Skip to content

This project is used to create and manage AWS resources with Terraform for study and learning purposes.

Notifications You must be signed in to change notification settings

viniciusferreira7/aws-terraform

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

10 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

AWS ECS Fargate Infrastructure with Terraform

Production-ready AWS infrastructure for deploying containerized applications using ECS Fargate, Application Load Balancer, and automated CI/CD with GitHub Actions.

πŸ—οΈ Architecture

Internet
    β”‚
    β”œβ”€β†’ Route 53 (optional)
    β”‚
    β”œβ”€β†’ ACM Certificate (HTTPS)
    β”‚
    β”œβ”€β†’ Application Load Balancer (Public Subnets)
    β”‚       β”œβ”€ HTTP β†’ HTTPS redirect
    β”‚       └─ HTTPS β†’ ECS Tasks
    β”‚
    └─→ ECS Fargate Tasks (Private Subnets)
            β”œβ”€ Auto-scaling (1-4 tasks)
            β”œβ”€ CloudWatch Logs
            └─ NAT Gateway β†’ Internet (outbound)

Supporting Infrastructure:
- ECR: Container image registry
- IAM: Task execution and application roles
- Security Groups: ALB and ECS isolation
- DynamoDB: Terraform state locking

πŸ“‹ Prerequisites

  • Terraform: >= 1.5.0
  • AWS CLI: Configured with credentials
  • Docker: For building and pushing container images
  • Git: For version control
  • GitHub Account: For CI/CD (optional)

πŸš€ Quick Start

1. Clone the Repository

git clone <your-repo-url>
cd aws-terraform

2. Configure AWS Profile

Update variables.tf or create terraform.tfvars:

profile = "admin_vinicius_ferreira"  # Your AWS CLI profile
region  = "us-east-1"

3. Initialize Terraform

terraform init

4. Deploy Infrastructure

For development environment:

# Plan
terraform plan -var-file=environments/dev.tfvars

# Apply
terraform apply -var-file=environments/dev.tfvars

5. Build and Push Container Image

# Get ECR repository URL from Terraform outputs
ECR_REPO=$(terraform output -raw ecr_repository_url)

# Login to ECR
aws ecr get-login-password --region us-east-1 | docker login --username AWS --password-stdin $ECR_REPO

# Build and push
docker build -t my-app .
docker tag my-app:latest $ECR_REPO:latest
docker push $ECR_REPO:latest

6. Update Container Image

Update environments/dev.tfvars:

container_image = "<ecr-repository-url>:latest"

Then apply again:

terraform apply -var-file=environments/dev.tfvars

7. Access Your Application

# Get ALB URL
terraform output alb_url

Visit the URL in your browser!

πŸ“ Project Structure

.
β”œβ”€β”€ modules/
β”‚   β”œβ”€β”€ ecr/              # Container registry
β”‚   β”œβ”€β”€ networking/       # VPC, subnets, NAT
β”‚   β”œβ”€β”€ security-groups/  # ALB and ECS security groups
β”‚   β”œβ”€β”€ iam/             # ECS task roles
β”‚   β”œβ”€β”€ alb/             # Application Load Balancer
β”‚   └── ecs/             # ECS Fargate cluster and service
β”œβ”€β”€ environments/
β”‚   β”œβ”€β”€ dev.tfvars       # Development configuration
β”‚   β”œβ”€β”€ staging.tfvars   # Staging configuration
β”‚   └── prod.tfvars      # Production configuration
β”œβ”€β”€ docs/
β”‚   β”œβ”€β”€ architecture.md  # Architecture details
β”‚   β”œβ”€β”€ deployment.md    # Deployment guide
β”‚   └── runbook.md       # Operations runbook
β”œβ”€β”€ .github/
β”‚   └── workflows/
β”‚       └── terraform.yml # CI/CD pipeline
β”œβ”€β”€ main.tf              # Main infrastructure
β”œβ”€β”€ variables.tf         # Input variables
β”œβ”€β”€ outputs.tf           # Output values
β”œβ”€β”€ versions.tf          # Terraform and provider versions
β”œβ”€β”€ locals.tf            # Local values
β”œβ”€β”€ acm.tf              # ACM certificate (optional)
└── iam-github-actions.tf # GitHub OIDC for CI/CD

πŸ”§ Module Overview

ECR Module

  • Container image registry
  • Image scanning enabled
  • Lifecycle policy (keep last 10 images)

Networking Module

  • VPC with public and private subnets
  • Internet Gateway for public subnets
  • NAT Gateway for private subnet outbound traffic
  • Multi-AZ deployment (us-east-1a, us-east-1b)

Security Groups Module

  • ALB security group (allow 80/443 from internet)
  • ECS security group (allow traffic from ALB only)

IAM Module

  • Task execution role (ECR pull, CloudWatch Logs)
  • Task role (application permissions)

ALB Module

  • Internet-facing Application Load Balancer
  • HTTP β†’ HTTPS redirect
  • Health checks for ECS tasks

ECS Module

  • ECS Fargate cluster
  • Task definition with configurable CPU/memory
  • ECS service with ALB integration
  • Auto-scaling based on CPU and memory
  • CloudWatch logging

🌍 Environments

Development (dev.tfvars)

  • 1 task (256 CPU, 512 MB memory)
  • HTTP only (no HTTPS)
  • Minimal auto-scaling (1-2 tasks)
  • 7-day log retention
  • ECS Exec enabled for debugging

Staging (staging.tfvars)

  • 2 tasks (512 CPU, 1024 MB memory)
  • Optional HTTPS
  • Moderate auto-scaling (2-4 tasks)
  • 14-day log retention

Production (prod.tfvars)

  • 2+ tasks (512 CPU, 1024 MB memory)
  • HTTPS required
  • Aggressive auto-scaling (2-10 tasks)
  • 30-day log retention
  • Deletion protection enabled
  • ECS Exec disabled

πŸ€– CI/CD with GitHub Actions

Setup

  1. Create GitHub OIDC provider and role:

    # Update iam-github-actions.tf with your GitHub repo
    # Then apply
    terraform apply
  2. Add GitHub secrets:

    • AWS_REGION: us-east-1
    • AWS_ROLE_ARN: (from terraform output)
  3. Configure environment protection (Settings > Environments):

    • Create "production" environment
    • Add required reviewers

Workflow

  • Push to PR: Runs terraform fmt, validate, and plan
  • Merge to main: Runs terraform apply (requires approval)
  • Plan output is posted as PR comment

πŸ’° Cost Estimate

Monthly costs (us-east-1, dev environment):

Resource Cost
NAT Gateway ~$32 + data transfer
Application Load Balancer ~$16 + LCU
ECS Fargate (1 task, 0.25 vCPU, 0.5 GB) ~$7.50
CloudWatch Logs ~$5
ECR Storage ~$1
Total ~$65-100/month

Cost Optimization

  • Use single NAT Gateway (saves ~$32/month)
  • Scale down during off-hours
  • Reduce log retention
  • Right-size tasks based on actual usage
  • Consider Fargate Spot for non-critical workloads (70% savings)

πŸ”’ Security Best Practices

  • βœ… ECS tasks in private subnets (no direct internet access)
  • βœ… Security groups with least privilege
  • βœ… Separate IAM roles for execution and application
  • βœ… Secrets via AWS Secrets Manager
  • βœ… ECR image scanning enabled
  • βœ… HTTPS with ACM certificates (production)
  • βœ… CloudWatch logging enabled
  • βœ… State locking with DynamoDB
  • βœ… OIDC for GitHub Actions (no hardcoded credentials)

πŸ“Š Monitoring

CloudWatch Logs

# Tail logs
aws logs tail /ecs/dev-app --follow

# Query logs
aws logs filter-log-events \
  --log-group-name /ecs/dev-app \
  --filter-pattern "ERROR"

ECS Service

# Describe service
aws ecs describe-services \
  --cluster dev-cluster \
  --services dev-app-service

# List tasks
aws ecs list-tasks --cluster dev-cluster

# Describe task
aws ecs describe-tasks \
  --cluster dev-cluster \
  --tasks <task-id>

ALB Health

# Check target health
aws elbv2 describe-target-health \
  --target-group-arn <target-group-arn>

πŸ› Troubleshooting

Tasks Not Starting

# Check service events
aws ecs describe-services --cluster <cluster> --services <service>

# Check task stopped reason
aws ecs describe-tasks --cluster <cluster> --tasks <task-id>

Common issues:

  • Invalid container image
  • Insufficient IAM permissions
  • Health check failures
  • Resource constraints

Health Check Failures

  • Ensure your app responds with HTTP 200 on health check path
  • Check application logs in CloudWatch
  • Verify security groups allow ALB β†’ ECS traffic
  • Increase health check timeout if app is slow to start

High Costs

  • Check CloudWatch metrics for unused resources
  • Review auto-scaling settings
  • Consider scaling down during off-hours
  • Reduce log retention
  • Use Fargate Spot for non-critical workloads

πŸ“š Additional Resources

🀝 Contributing

  1. Fork the repository
  2. Create a feature branch
  3. Make your changes
  4. Run terraform fmt -recursive
  5. Submit a pull request

πŸ“ License

This project is for educational purposes.

πŸ‘€ Author

Vinicius Ferreira - Rocketseat AWS Study Program

πŸ™ Acknowledgments

  • Rocketseat AWS Study Program
  • Terraform AWS Provider Team
  • AWS Documentation

About

This project is used to create and manage AWS resources with Terraform for study and learning purposes.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages