Amazon ECS on Fargate
Serverless containers without node ops for fast iteration and spiky services
ECS on Fargate
When to use
- You want containers without node ops: fast iteration, spiky services, simpler security posture.
Knobs that matter
- Task sizing (vCPU/mem combos), ephemeral storage, platform version.
- Networking:
awsvpcENI per task (IP management), SGs. - Fargate Spot for interrupt-tolerant tasks (batch/async). ([Amazon Web Services, Inc.][3])
Pricing mental model
- Pay for requested vCPU + memory for the task runtime (billed per-second; min 1 minute; ECS notes round-up rules). ([Amazon Web Services, Inc.][2])
- Mental model: “Fargate is convenience tax; for steady workloads ECS/EC2 is cheaper.”
Heuristics
- Default to Fargate for new services until you have steady-state utilization data.
- Migrate to ECS/EC2 when utilization is stable and cost matters.
Terraform (Fargate service)
resource "aws_ecs_cluster" "this" { name = var.name }
resource "aws_cloudwatch_log_group" "lg" {
name = "/ecs/${var.name}"
retention_in_days = 14
}
resource "aws_ecs_task_definition" "task" {
family = var.name
network_mode = "awsvpc"
requires_compatibilities = ["FARGATE"]
cpu = "1024"
memory = "2048"
execution_role_arn = var.execution_role_arn
task_role_arn = var.task_role_arn
container_definitions = jsonencode([{
name = "app"
image = var.image
portMappings = [{ containerPort = var.container_port, protocol = "tcp" }]
logConfiguration = {
logDriver = "awslogs"
options = {
awslogs-group = aws_cloudwatch_log_group.lg.name
awslogs-region = var.region
awslogs-stream-prefix = "app"
}
}
}])
}
resource "aws_ecs_service" "svc" {
name = var.name
cluster = aws_ecs_cluster.this.id
task_definition = aws_ecs_task_definition.task.arn
desired_count = 2
launch_type = "FARGATE"
network_configuration {
subnets = var.private_subnet_ids
security_groups = [var.sg_id]
assign_public_ip = false
}
}
variable "name" { type = string }
variable "region" { type = string }
variable "image" { type = string }
variable "container_port" { type = number }
variable "private_subnet_ids" { type = list(string) }
variable "sg_id" { type = string }
variable "execution_role_arn" { type = string }
variable "task_role_arn" { type = string }