--- 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.