Files
Hugo/content/blog/terraform-aws-ecs.md
T

71 lines
2.4 KiB
Markdown

---
title: "Deploying to AWS ECS with Terraform"
date: 2026-05-14T10:00:00+08:00
draft: false
description: "Infrastructure as code from scratch: VPC, subnets, security groups, ECR repository, ECS service with Fargate, and an ALB in front. Every resource explained."
tags:
- AWS
- Terraform
- DevOps
---
ECS with Fargate is the sweet spot between managing servers and going full serverless. Terraform makes it reproducible.
## The Stack
Here's what we need to provision:
| Resource | Purpose |
|----------|---------|
| VPC | Isolated network |
| Public & private subnets | Multi-AZ placement |
| Security groups | Network access control |
| ECR repository | Container image storage |
| ECS cluster + service | Run containers |
| ALB + target group | Traffic distribution |
## Security Groups: Getting Them Right
The key is getting the security groups right — one misconfigured rule and your containers can't talk to each other, or worse, your database is exposed to the internet.
```hcl
resource "aws_security_group" "ecs_service" {
name = "ecs-service-sg"
vpc_id = aws_vpc.main.id
ingress {
from_port = 3000
to_port = 3000
protocol = "tcp"
security_groups = [aws_security_group.alb.id]
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
}
```
The principle: **allow the minimum**. The ALB security group allows inbound from the internet on 80/443. The ECS security group only allows inbound from the ALB. The database security group only allows inbound from ECS.
## Fargate Configuration
Fargate abstracts the EC2 instances. You specify CPU and memory, and AWS handles the rest. For most web services, 0.25 vCPU / 512 MB is a good starting point — scale up based on load testing, not guessing.
## CI/CD Integration
After Terraform creates the infrastructure, your CI pipeline needs to:
1. Build and tag the Docker image
2. Push to ECR
3. Update the ECS service with the new task definition
Use a Terraform backend with state locking — S3 + DynamoDB is the standard approach. Without state locking, two people running `terraform apply` at the same time can corrupt your infrastructure state.
## Cost Notes
Fargate is more expensive per vCPU-hour than raw EC2, but you save the operational cost of patching instances and managing capacity. For small-to-medium workloads, the difference is negligible compared to the engineering time saved.