Röviden: A Fargate leveszi a válladról az EC2-hostok kezelését: csak a konténert adod meg, az AWS futtatja. Felépítünk egy teljes prod setupot ALB-vel, health checkkel, cél-alapú autoscalinggel és privát taskokkal — végig IaC-kal.
Ha van egy konténerbe csomagolt alkalmazásod, de nem akarsz Kubernetes-klasztert üzemeltetni, az ECS Fargate a legkevesebb súrlódással járó út prodba. A Fargate szerver nélküli: nem kell EC2-hostokat foglalni, patchelni, skálázni — csak megadod, mennyi CPU és memória kell a taskodnak, és az AWS futtatja. Ebben a cikkben egy teljes production setupot építünk: ALB a bejövő forgalomnak, ECS service Fargate-en, privát subnetben futó taskok, health check és terhelés-alapú autoscaling — mind Terraformmal.
A cél-architektúra
Az ALB a publikus subnetekben fogadja a HTTPS-t, és a privát subnetekben futó Fargate-taskokra osztja a forgalmat egy target groupon keresztül. Az ECS service tartja a kívánt példányszámot, az Application Auto Scaling pedig a CPU-terhelés alapján fel/le skálázza.
Fargate vagy EC2 launch type?
Az ECS kétféleképp futtathat taskot: Fargate-en (szerver nélkül) vagy saját EC2-hostokon. A Fargate egyszerűbb és operatívan olcsóbb; az EC2 akkor kerül képbe, ha nagyon nagy, állandó terhelésnél a compute egységára számít, vagy speciális (pl. GPU) hardver kell.
| Szempont | Fargate | EC2 launch type |
|---|---|---|
| Host-kezelés | nincs (AWS) | te patchelsz, skálázol |
| Számlázás | task CPU/mem szerint | EC2-instance szerint |
| Indulási idő | pár másodperc | AMI/host függő |
| Nagy, állandó terhelés | drágább lehet | olcsóbb lehet |
| Mikor? | a legtöbb esetben | GPU, nagyon nagy skála |
A cluster és a task definition, Terraformban
A task definition a szíve mindennek: megmondja, milyen konténer(ek), mennyi CPU/memória, milyen portok és környezeti változók. A awslogs driver a CloudWatchba küldi a logokat.
resource "aws_ecs_cluster" "main" {
name = "${var.project}-cluster"
setting {
name = "containerInsights"
value = "enabled"
}
tags = local.tags
}
resource "aws_cloudwatch_log_group" "app" {
name = "/ecs/${var.project}"
retention_in_days = 30
tags = local.tags
}
resource "aws_ecs_task_definition" "app" {
family = "${var.project}-app"
requires_compatibilities = ["FARGATE"]
network_mode = "awsvpc"
cpu = 512
memory = 1024
execution_role_arn = aws_iam_role.task_execution.arn
task_role_arn = aws_iam_role.task.arn
container_definitions = jsonencode([{
name = "app"
image = "${var.ecr_repo_url}:${var.image_tag}"
essential = true
portMappings = [{ containerPort = 8080, protocol = "tcp" }]
logConfiguration = {
logDriver = "awslogs"
options = {
"awslogs-group" = aws_cloudwatch_log_group.app.name
"awslogs-region" = var.region
"awslogs-stream-prefix" = "app"
}
}
}])
tags = local.tags
}Az ALB és a target group health checkkel
Az ALB egy target grouphoz irányítja a forgalmat, ami a taskok 8080-as portját célozza. A health check kritikus: az ALB csak egészséges taskokra oszt forgalmat, és a beteget kiveszi a rotációból.
resource "aws_lb" "app" {
name = "${var.project}-alb"
load_balancer_type = "application"
subnets = var.public_subnet_ids
security_groups = [var.alb_sg_id]
tags = local.tags
}
resource "aws_lb_target_group" "app" {
name = "${var.project}-tg"
port = 8080
protocol = "HTTP"
vpc_id = var.vpc_id
target_type = "ip" # Fargate-nél kötelező az ip target type
health_check {
path = "/healthz"
healthy_threshold = 2
unhealthy_threshold = 3
interval = 15
timeout = 5
matcher = "200"
}
tags = local.tags
}
resource "aws_lb_listener" "https" {
load_balancer_arn = aws_lb.app.arn
port = 443
protocol = "HTTPS"
ssl_policy = "ELBSecurityPolicy-TLS13-1-2-2021-06"
certificate_arn = var.certificate_arn
default_action {
type = "forward"
target_group_arn = aws_lb_target_group.app.arn
}
}Az ECS service privát subnetben
A service tartja a kívánt taskszámot, privát subnetben (nincs publikus IP), és a taskokat az ALB target grouphoz köti. A depends_on a listenerre azért kell, hogy a service ne induljon a forgalmi útvonal kész léte előtt.
resource "aws_ecs_service" "app" {
name = "${var.project}-svc"
cluster = aws_ecs_cluster.main.id
task_definition = aws_ecs_task_definition.app.arn
desired_count = 2
launch_type = "FARGATE"
network_configuration {
subnets = var.private_subnet_ids
security_groups = [var.app_sg_id]
assign_public_ip = false
}
load_balancer {
target_group_arn = aws_lb_target_group.app.arn
container_name = "app"
container_port = 8080
}
depends_on = [aws_lb_listener.https]
tags = local.tags
}Autoscaling: skálázz a valós terhelésre
A cél-alapú (target tracking) autoscaling a legkényelmesebb: megadsz egy célt (pl. 60% átlagos CPU), és az AWS annyi taskot tart fenn, hogy ezt tartani tudja. Nincs küszöb-hackelés, nincs kézi be/kikapcsolás.
resource "aws_appautoscaling_target" "ecs" {
max_capacity = 10
min_capacity = 2
resource_id = "service/${aws_ecs_cluster.main.name}/${aws_ecs_service.app.name}"
scalable_dimension = "ecs:service:DesiredCount"
service_namespace = "ecs"
}
resource "aws_appautoscaling_policy" "cpu" {
name = "${var.project}-cpu-target"
policy_type = "TargetTrackingScaling"
resource_id = aws_appautoscaling_target.ecs.resource_id
scalable_dimension = aws_appautoscaling_target.ecs.scalable_dimension
service_namespace = aws_appautoscaling_target.ecs.service_namespace
target_tracking_scaling_policy_configuration {
predefined_metric_specification {
predefined_metric_type = "ECSServiceAverageCPUUtilization"
}
target_value = 60
scale_in_cooldown = 120
scale_out_cooldown = 60
}
}A deploy-életciklus
Egy új verzió kigördülése így néz ki: új image az ECR-be, új task definition revízió, a service pedig fokozatosan cseréli a taskokat, miközben az ALB health check őrködik, hogy csak egészséges task kapjon forgalmat.
Mit jelent ez neked?
Ez a setup — cluster, task definition, ALB target grouppal és health checkkel, privát ECS service és cél-alapú autoscaling — egy teljes, önmagát skálázó és gyógyító konténer-platform, EC2-host nélkül. A Fargate elveszi a legfájdalmasabb operatív terhet (host-patch, cluster-skálázás), te pedig arra koncentrálhatsz, ami számít: az alkalmazásra. A kulcsdöntések itt is láthatók a kódban — ip target type, health check path, autoscaling cél, circuit breaker —, és pont ezek azok, amiket kézzel a legkönnyebb elrontani. Terraformmal viszont egyszer állítod be jól, és utána reprodukálható marad.