ECS 컨테이너, ALB 청사진, Terraform 모듈과 스케일링 차트의 평면도
글 요약
AWS ECS + Terraform 자동화로 ALB, 오토 스케일링, 무중단 배포까지 production 환경 인프라를 코드로 통제하는 방법. 컨테이너 운영에서 자주 발생하는 설정 누락, 스케일 지연, 배포 사고를 줄이는 실전 구성 패턴을 정리합니다.
“ECS 콘솔에서 클릭클릭으로 서비스 만들었는데, 환경이 3개가 되니까 누가 뭘 바꿨는지 모릅니다”
Terraform으로 ECS 인프라를 코드로 잠그면 환경 간 드리프트를 없애고, ALB부터 오토 스케일링까지 재현 가능한 production 셋업을 단일 파일로 관리할 수 있습니다. 이 글에서는 실제 운영자가 자주 겪는 실패 사례와 비교 분석까지 한 번에 풀어드릴게요.
컨테이너 서비스를 운영하다 보면 처음엔 단순하게 시작했던 구성이, 트래픽이 붙고 팀이 커지면서 어느새 누가 어떤 설정으로 바꿨는지 추적이 안 되는 상태가 됩니다. 콘솔에서 직접 만든 ECS 서비스는 코드 리뷰가 불가능하고, 같은 사양으로 dev/staging/prod를 복제하려면 결국 수작업이 따라오거든요. Terraform을 IaC 도구로 채택하면 모듈화, plan 기반 변경 검토, Git 기반 이력 관리라는 세 가지 큰 이점을 동시에 가져갈 수 있습니다.
📑 목차
📌 이 글의 핵심 정리
- ECS 인프라를 코드로 관리하면 환경 간 드리프트를 원천 차단하고 plan 단계에서 변경 영향을 사전 검토할 수 있습니다.
- ALB health check, target group deregistration delay, ECS task 정의 버전은 무중단 배포의 3대 축이므로 Terraform에서 명시적으로 고정해야 합니다.
- 오토 스케일링은 단순히 desired count만 올리는 게 아니라 CPU·메모리·ALB 요청 수 메트릭을 조합해 정책화해야 응답 지연을 막을 수 있습니다.
ECS + Terraform을 production에 도입하는 이유
ECS는 컨테이너 오케스트레이션을 AWS 네이티브로 다룰 수 있어서, 별도의 컨트롤 플레인을 설치·운영할 필요 없이 ALB·IAM·CloudWatch와 매끄럽게 붙는다는 강점이 있습니다. EKS 대비 학습 곡선이 완만하고, Fargate를 쓰면 EC2 인스턴스 패치·용량 계획까지 AWS로 위임할 수 있거든요.
Terraform이 가져오는 결정적 차이
콘솔 운영에서는 task 정의의 환경 변수 한 개를 바꿔도 운영자가 직접 들어가야 하고, 누가 바꿨는지 audit 로그를 뒤져야 합니다. Terraform으로 코드를 작성하면 git diff 한 줄이 곧 변경 이력이 되고, PR 리뷰를 통해 동료가 검토할 수 있어요.
Terraform 상태 파일과 원격 백엔드
production 인프라를 다루는 만큼 tfstate 파일은 반드시 S3 + DynamoDB 락으로 관리하셔야 합니다. 로컬에 두면 동시 apply로 리소스가 깨질 수 있거든요. 원격 백엔드를 구성해두면 팀원이 늘어도 안전하게 협업할 수 있습니다.
네트워크 베이스 구성: VPC·서브넷·보안그룹
ECS든 EKS든 VPC가 깨지면 모든 게 같이 무너집니다. 그래서 production에서는 처음부터 multi-AZ 구조로 시작하는 게 안전합니다. 단일 AZ로 시작해서 나중에 분리하려면 거의 모든 서브넷과 라우팅을 다시 그려야 해서요.
public/private 서브넷 분리의 핵심
ALB는 public 서브넷에 두고, ECS task는 private 서브넷에 둡니다. 이렇게 분리해야 task가 직접 인터넷을 노출하지 않고, NAT Gateway를 통해서만 외부 API를 호출할 수 있거든요. 데이터베이스는 별도의 isolated 서브넷에 두면 라우팅 테이블에서 아예 인터넷 경로를 제거할 수 있습니다.
보안그룹은 최소 권한으로
ECS 보안그룹은 ALB 보안그룹의 ID만 source로 받아 inbound 80/443을 허용하고, outbound는 HTTPS만 허용하도록 좁히는 게 정석입니다. 0.0.0.0/0 인바운드는 절대 권장하지 않습니다. 나중에 침투 사고가 발생했을 때 추적 범위가 너무 넓어지거든요.
⚠️ 네트워크 구성 주의
- VPC CIDR를 10.0.0.0/16처럼 너무 작게 잡으면 나중에 peered VPC나 Transit Gateway 붙일 때 주소가 부족할 수 있습니다. 처음부터 /20 이상으로 여유 있게 잡아두세요.
ALB와 ECS 클러스터·서비스 연결하기
ALB는 ECS의 얼굴이라고 할 수 있습니다. 사용자가 처음 마주하는 접점이고, health check의 결과에 따라 오토 스케일링과 배포가 모두 영향을 받거든요. Terraform에서 ALB 리스너와 target group을 정의할 때 몇 가지 옵션을 반드시 명시해야 합니다.
target group의 핵심 옵션
deregistration_delay를 너무 짧게 잡으면 배포 중 기존 task가 응답을 마무리하기도 전에 연결이 끊어집니다. 반대로 너무 길게 잡으면 롤링이 늦어지는데, 일반적으로 30초 정도가 무난한 시작점입니다. health check는 task가 실제로 받는 엔드포인트 기준으로 설정하셔야 해요. 루트(/ )가 200을 반환해도 실제 비즈니스 API는 죽어 있을 수 있거든요.
ECS service의 desired_count와 deployment 전략
ECS service에서 deployment_minimum_healthy_percent와 deployment_maximum_percent를 함께 설정해야 합니다. 100/200 조합이면 무중단 롤링이 가능하고, 50/100처럼 잡으면 비용을 아낄 수 있지만 배포 중 capacity가 줄어듭니다. 트래픽 패턴에 맞춰 조정하시는 게 핵심이에요.
task 정의와 IAM 역할 분리
task role과 execution role을 분리하는 게 production 베스트 프랙티스입니다. execution role은 이미지를 pull하고 CloudWatch에 로그를 쓰는 용도로만, task role은 애플리케이션이 실제로 S3나 Secrets Manager에 접근할 때 사용하도록 구분하시면 최소 권한 원칙을 지킬 수 있습니다.
오토 스케일링 설정과 흔한 실패 사례
오토 스케일링은 단순히 “트래픽 오면 늘리기”가 아닙니다. 실제로는 scale-out이 늦거나, scale-in이 너무 빨라서 응답이 흔들리는 경우가 매우 많거든요. 여기서는 제가 직접 겪었던 실패 사례 하나를 먼저 풀어드리고, 이를 해결하는 노하우를 정리해 보겠습니다.
실패 사례: 새벽 트래픽 폭증에 Fargate task가 안 늘어난 사건
처음 ECS 서비스를 셋업할 때 오토 스케일링을 CPU 70% 기준 target tracking 1개만 걸어뒀습니다. 평소엔 문제없이 작동했는데, 어느 새벽 특정 마케팅 캠페인 때문에 트래픽이 평소의 10배로 치솟은 적이 있어요. 그런데 CPU 메트릭은 올라오기까지 최소 1~2분의 지연이 있는데, 그 사이 사용자는 이미 503을 마주하고 있었습니다.
근본 원인은 메트릭 단일 의존
CPU는 결국 task가 실제로 부하를 받아야 상승합니다. 즉, task가 이미 적체 상태가 된 다음에야 스케일링 신호가 가는 거예요. 더 빨리 반응하려면 ALBRequestCountPerTarget 같은 선행 지표를 함께 걸어둬야 합니다. 요청 수가 임계치를 넘는 순간 즉시 scale-out이 시작되거든요.
⚠️ 오토 스케일링 흔한 함정
- step scaling의 cooldown을 너무 짧게 잡으면 스케일 아웃·인 진동이 발생합니다. 최소 60초 이상으로 두는 게 안정적입니다.
- Fargate의 warm-up 시간을 고려해 min capacity를 평시 트래픽의 1.5배 정도로 잡아두면 갑작스러운 요청에도 여유가 생깁니다.
해결 노하우: 복합 지표 + 예측 스케일링
현재는 ALBRequestCountPerTarget 1000/분, CPU 60%, 메모리 70% 세 가지 target tracking 정책을 동시에 걸어두고, 평소에는 가장 보수적인 메트릭이 발동하도록 우선순위를 조정해뒀습니다. 게다가 Application Auto Scaling의 예측 스케일링을 활성화해두면 주기적 트래픽 패턴도 미리 학습해서 미리 capacity를 확보해 줍니다.
EKS·EC2 직접 배포와의 구체적 비교
ECS가 항상 정답은 아닙니다. 팀 상황과 워크로드 특성에 따라 EKS나 EC2 직접 배포가 더 나을 때도 있거든요. 여기서는 production 관점에서 세 가지 옵션을 구체적으로 비교해 보겠습니다.
3가지 옵션의 핵심 차이 비교
| 비교 항목 | ECS + Fargate | EKS (Managed Node) | EC2 + Docker 직접 |
|---|---|---|---|
| 컨트롤 플레인 운영 | AWS 완전 관리 | AWS 관리 (K8s 버전 업은 직접) | 본인이 직접 |
| 학습 곡선 | 낮음 (AWS 콘솔 익히면 충분) | 높음 (K8s 생태계 이해 필요) | 중간 (Docker 지식 필요) |
| Terraform 모듈화 난이도 | 쉬움 (AWS 공식 provider 풍부) | 보통 (Helm·kubectl 연동 필요) | 쉬움 (단순 리소스 조합) |
| 예측 가능한 비용 | 중간 (vCPU·GB당 과금) | 높음 (control plane 비용 별도) | 낮음 (RI 활용 시) |
| 오토 스케일링 반응 속도 | 빠름 (Fargate 워밍 30~60초) | 느림 (노드 부팅 시간 포함) | 매우 느림 (AMI 부팅 + 컨테이너) |
| 적합한 시나리오 | 중소규모 MSA, 빠른 출시 | 대규모 MSA, K8s 생태계 활용 | 단순 API·배치성 워크로드 |
이 비교에서 제가 강조하고 싶은 통찰
단순히 “K8s가 더 강력하니까 EKS”라는 식으로 결정하면 안 됩니다. EKS는 노드 그룹 관리, Helm 차트 의존성, RBAC 등 운영할 게 ECS보다 압도적으로 많아요. 팀 인원 3~5명 규모에서 안정적인 production을 우선하려면 ECS + Terraform이 거의 항상 더 빠른 가치 제공을 해 줍니다. EKS로 가는 건 K8s 생태계 자체가 필요한 시점, 즉 cron·stateful workload·service mesh 같은 K8s 자원이 비즈니스 요구사항이 된 시점입니다.
운영 자동화 노하우와 배포 안정화 팁
ECS + Terraform은 셋업만 잘하면 운영 부담이 확 줄어듭니다. 마무리로 production에서 실제로 효과를 봤던 운영 자동화 팁 몇 가지를 정리합니다.
CI/CD 파이프라인 통합
GitHub Actions나 GitLab CI에서 terraform plan → 리뷰 → apply 흐름을 자동화해두면 PR 단계에서 변경 영향도를 누구나 볼 수 있습니다. 여기에 ECS task 정의의 이미지 태그를 git SHA로 자동 갱신하도록 연동하면 사람이 손댈 일이 거의 사라지거든요.
💡 ECS 운영 꿀팁
- 이미지 태그를 latest로 두지 마세요. 롤백이 필요한 순간에 어떤 버전이 실제로 떠 있는지 모호해집니다. git SHA나 semver를 사용하시면 됩니다.
- Secrets Manager·Parameter Store를 적극 활용하세요. 환경 변수로 직접 비밀번호를 넣는 순간 tfstate에 평문 비밀번호가 남는 보안 사고로 이어집니다.
모듈화로 재사용성 극대화
ECS 클러스터 모듈, ALB 모듈, 서비스 모듈을 각각 분리해서 변수로 환경(dev/prod)을 받게 설계하시면 코드 중복 없이 모든 환경을 동일한 패턴으로 운영할 수 있습니다. 처음엔 과한 추상화처럼 느껴질 수 있는데, 환경이 3개 이상이 되는 순간 효과가 폭발적으로 나타나거든요.
모니터링과 알람 자동화
CloudWatch 알람을 Terraform으로 함께 정의해두면, 새 서비스를 만들 때 필요한 알람도 자동으로 함께 배포됩니다. 5xx 비율, CPU 임계치, 메모리 임계치, task running count 네 가지는 최소한 베이스라인으로 걸어두시길 권합니다.
자주 묻는 질문
Q. Fargate와 EC2 launch type 중 무엇을 선택해야 하나요?
A. 특별한 이유(예: GPU, 사이드카 사이즈 커스터마이징)가 없다면 Fargate가 운영 부담이 훨씬 적습니다. EC2 launch type은 인스턴스 패치·용량 계획까지 본인이 해야 하므로, production 초기 단계에서는 거의 항상 Fargate를 권합니다.
Q. Terraform state 파일은 어디에 두는 게 안전한가요?
A. S3 버킷 + DynamoDB 락 테이블 조합이 사실상 표준입니다. S3에는 versioning과 암호화를 켜고, DynamoDB 락으로 동시 apply를 차단하셔야 production에서 사고를 막을 수 있습니다.
Q. ECS에서 Blue/Green 배포는 어떻게 구성하나요?
A. CodeDeploy를 ECS deployment controller로 연결하면 됩니다. Terraform의 aws_codedeploy_app, deployment_group 리소스와 ECS service의 deployment_controller 옵션을 함께 정의하시면 됩니다.
Q. ECS Fargate에서 컨테이너가 외부 IP가 필요한 경우 어떻게 하나요?
A. 대부분 NAT Gateway를 통해 outbound만 가능하도록 구성하시면 충분합니다. inbound가 꼭 필요한 특수 워크로드라면 AWS VPC Lattice 또는 API Gateway 패턴으로 우회하는 게 안전합니다.
ECS + Terraform 조합은 처음 한 번만 제대로 셋업해두면, 이후 운영에서는 거의 손대지 않아도 되는 안정적인 production 인프라를 제공합니다. 콘솔 클릭으로 시작했던 환경이 3개 이상이 되는 순간 반드시 마주칠 수밖에 없는 드리프트와 변경 추적 문제를 코드로 풀어내는 가장 현실적인 해법이라고 저는 보고 있습니다. 오늘 정리한 패턴이 production ECS 운영의 든든한 출발점이 되시길 바랍니다.
본 글의 모든 내용은 작성자인의 운영 경험을 바탕으로 한 일반적인 가이드이며, AWS·테라폼의 공식 문서 및 서비스 약관을 직접 확인하시고 적용하시길 권장합니다. 본문을 참고해 진행한 구성 및 운영 결과에 대한 책임은 사용자 본인에게 있으며, 서비스별 세부 사양과 가격 정책은 사전에 반드시 검증하시기 바랍니다.