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

2.4 KiB

title, date, draft, description, tags
title date draft description tags
Deploying to AWS ECS with Terraform 2026-05-14T10:00:00+08:00 false Infrastructure as code from scratch: VPC, subnets, security groups, ECR repository, ECS service with Fargate, and an ALB in front. Every resource explained.
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.

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.