AWS 실전 #6 비용 최적화와 대시보드: 트랙 마무리
#1 ~ #5에서 인프라 / DB / CI/CD / IaC / 모니터링까지, 운영 가능한 시스템이 갖춰졌습니다. 마지막으로 남은 주제는 얼마나 들고 있는가, 그리고 그 비용을 어떻게 줄이는가입니다.
이 글의 절반은 비용 최적화, 절반은 AWS 트랙 27편 회고입니다.
청구서가 어디서 새는가 #
기초 #3 비용 관리에서 결제 알림과 Cost Explorer의 기본은 잡았습니다. 이번 글은 그 위에서 운영 시스템의 비용을 실제로 줄이는 단계.
전형적인 작은 운영 (ECS Fargate + RDS + ALB + CloudFront + Logs)의 월 청구서 비율:
| 자원 | 비율 | 의미 |
|---|---|---|
| ECS Fargate (vCPU + 메모리시간) | 30~50% | 가장 큰 비용 항목 |
| RDS (인스턴스 + Storage + IO) | 20~30% | Multi-AZ 면 2x |
| NAT Gateway / Egress | 10~20% | 자주 잊히는 비용 항목 |
| ALB / 트래픽 | 5~10% | 시간 + LCU |
| CloudWatch Logs / Metrics | 5~10% | retention 누락 시 폭주 |
| S3 / ECR | 2~5% | 이미지 / 객체 누적 |
| 기타 | 5% | DNS, KMS, Secrets, … |
이 표를 보고 “내 청구서랑 닮았다” 하면, 다음의 패턴이 통합니다.
1) Cost Explorer: 어디서 돈이 나가는지부터 #
Cost Explorer가 청구서를 슬라이스 / 다이스합니다. 콘솔에서:
1) 서비스별 : Fargate vs RDS vs Logs (가장 큰 비용 항목)
2) 태그별 : env=prod vs env=dev (환경 분리 비용)
3) 사용 유형별 : DataTransfer-Out-Bytes vs BoxUsage 등
4) 리전별 : 잠자고 있는 다른 리전 자원 (#1 함정)
5) 시간 추세 : 어제부터 갑자기 오른 항목CLI로도 #
aws ce get-cost-and-usage \
--time-period Start=$(date -u +%Y-%m-01),End=$(date -u +%Y-%m-%d) \
--granularity DAILY \
--metrics BlendedCost \
--group-by Type=DIMENSION,Key=SERVICECost Anomaly Detection #
ML 기반으로 이상치를 감지합니다. 평소 패턴에서 벗어나면 자동으로 알림을 보냅니다.
aws ce create-anomaly-monitor \
--anomaly-monitor '{
"MonitorName": "blog-services",
"MonitorType": "DIMENSIONAL",
"MonitorDimension": "SERVICE"
}'기초 #3의 결제 알림이 “임계 넘으면” 이라면, Cost Anomaly는 “평소와 다르면”, 미묘한 누수를 잡는 도구입니다.
2) Compute 비용: Fargate의 세 가지 포인트 #
A) Right Sizing: 진짜 필요한 만큼만 #
CloudWatch Container Insights (#5)의 평균 CPU / 메모리 사용률을 보고 작업 크기를 조정합니다.
현재: cpu=1024, memory=2048
관찰: 평균 CPU 15%, p95 35%, 메모리 평균 30%
조정: cpu=512, memory=1024 → 비용 50% 절감CPU 평균이 30~50% 영역에서 도는 게 건강한 수준. 20% 미만이면 너무 큼 (그래도 burst 여유는 두기).
작은 환경에선 Compute Optimizer가 자동으로 추천을 해줍니다. 콘솔에서 한 번 켜기.
B) Fargate Spot: 70% 저렴 #
배치성 / 재시작 가능한 작업은 Fargate Spot으로:
resource "aws_ecs_service" "this" {
capacity_provider_strategy {
capacity_provider = "FARGATE"
weight = 1 # base on-demand
base = 2
}
capacity_provider_strategy {
capacity_provider = "FARGATE_SPOT"
weight = 4 # 추가는 Spot 우선
}
}위 패턴: 항상 2개는 on-demand, 그 이상은 4:1 비율로 Spot입니다. 부하가 줄면 Spot부터 정리합니다.
**중단(interruption)**이 발생하면 ECS가 새 작업을 띄우지만 ~120초 다운타임이 생길 수 있습니다. 운영 트래픽에선 일부만 Spot으로 두고, 100% Spot은 피합니다.
C) Graviton (ARM): 20% 저렴 + 20% 빠름 #
db.t4g.* (RDS), Fargate ARM 옵션, EC2 Graviton (m7g, c7g)은 AWS의 ARM 칩. 컨테이너 이미지가 ARM 빌드 가능하면 굳이 안 쓸 이유가 없습니다.
# 빌드
docker buildx build --platform linux/amd64,linux/arm64 \
-t $REPO/blog-api:v1 --push .resource "aws_ecs_task_definition" "this" {
cpu = "512"
memory = "1024"
runtime_platform {
cpu_architecture = "ARM64"
operating_system_family = "LINUX"
}
}전제: 사용 라이브러리가 모두 ARM과 호환됩니다. 대부분의 Python / Node / Go 패키지는 OK. 일부 native bindings는 검증이 필요합니다.
3) Savings Plans / Reserved Capacity #
Fargate / EC2 / Lambda에 적용할 수 있는 약정 할인 제도입니다.
| 종류 | 할인 | 약정 |
|---|---|---|
| Compute Savings Plan | 최대 66% | 1년 / 3년, $/h 약정 |
| EC2 Instance SP | 최대 72% | 인스턴스 패밀리까지 약정 |
| RDS Reserved | 최대 65% | 인스턴스 클래스 + 리전 |
Compute SP가 가장 유연 (Fargate / EC2 / Lambda 모두 적용). 안정 운영에 들어간 시점부터 검토. 처음엔 절대 약정 X (트래픽 / 아키텍처가 흔들릴 때).
운영 시작 ~ 3개월 : 약정 X (변화가 빠른 환경)
3개월 ~ 6개월 : 사용량 분석, 1년 SP 검토 시작
6개월 + : 안정 사용량의 60~70% 만큼 1년 약정전체 100% 를 약정하면 트래픽이 줄 때 손해. 항상 안전 마진을 둡니다.
4) Storage / Logs: 가장 자주 새는 항목 #
CloudWatch Logs #
#5에서 강조한 retention. 모든 그룹에 적용:
resource "aws_cloudwatch_log_group" "ecs" {
for_each = toset(["/ecs/blog-api", "/ecs/blog-api-migrate"])
name = each.key
retention_in_days = 30
}S3 #
오래된 객체를 자동으로 저렴한 클래스로:
resource "aws_s3_bucket_lifecycle_configuration" "logs" {
bucket = aws_s3_bucket.logs.id
rule {
id = "to-ia-then-glacier"
status = "Enabled"
transition { days = 30, storage_class = "STANDARD_IA" }
transition { days = 90, storage_class = "GLACIER" }
expiration { days = 365 }
}
}ECR #
오래된 이미지를 자동 삭제:
resource "aws_ecr_lifecycle_policy" "blog_api" {
repository = aws_ecr_repository.blog_api.name
policy = jsonencode({
rules = [{
rulePriority = 1
description = "최근 30개만 유지"
selection = { tagStatus = "any", countType = "imageCountMoreThan", countNumber = 30 }
action = { type = "expire" }
}]
})
}5) Network: NAT와 Egress #
운영 청구서를 처음 보는 사람이 가장 놀라는 항목: NAT Gateway와 Egress.
시간당 $0.045
GB당 $0.045 (처리)
+ Egress $0.09/GB (인터넷으로)작은 시스템에서도 NAT 한 개가 월 ~$32 + 트래픽. 패턴별 절약:
| 패턴 | 효과 |
|---|---|
| VPC Endpoint for S3, DynamoDB | 완전 무료, NAT 트래픽 분산 |
| VPC Endpoint for ECR, Logs, Secrets | 시간당 ~$0.01 + GB ~$0.01 (NAT보다 저렴) |
| CloudFront 앞에 두기 | Origin → CloudFront 무료, CloudFront → 사용자 GB ~$0.085 (지역에 따라) |
| 단일 NAT (개발 환경) | AZ 별 NAT가 아니라 한 NAT. 가용성 ↓ |
Endpoint 한 줄 #
resource "aws_vpc_endpoint" "ecr_api" {
vpc_id = aws_vpc.this.id
service_name = "com.amazonaws.${var.region}.ecr.api"
vpc_endpoint_type = "Interface"
subnet_ids = aws_subnet.private[*].id
security_group_ids = [aws_security_group.endpoints.id]
private_dns_enabled = true
}ECS 작업이 ECR에서 이미지를 받을 때 NAT가 아니라 엔드포인트를 통해 받습니다. NAT 트래픽 / 비용을 모두 줄일 수 있습니다.
6) 태깅: 비용을 분류 가능하게 #
태그가 없으면 청구서가 한 덩어리입니다. 태그가 있으면 환경 / 팀 / 프로젝트 별로 슬라이스.
provider "aws" {
default_tags {
tags = {
Environment = var.environment
Project = "blog-api"
ManagedBy = "terraform"
CostCenter = "product-blog"
}
}
}provider의 default_tags는 모든 자원에 자동 적용됩니다. 운영의 핵심입니다.
Cost Allocation Tag 활성화 #
태그를 넣어도 콘솔의 Billing → Cost Allocation Tags에서 활성화하지 않으면 Cost Explorer가 분류해주지 않습니다. 설정 → 태그 활성 → ~24h 대기 → 사용 가능합니다.
태그 강제 (SCP / IAM Condition) #
태그 없는 자원 생성 차단. AWS Organizations의 SCP 또는 IAM 정책의 Condition:
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Deny",
"Action": ["ec2:RunInstances", "rds:CreateDBInstance"],
"Resource": "*",
"Condition": {
"Null": { "aws:RequestTag/Environment": "true" }
}
}]
}7) 운영 비용 대시보드 #
CloudWatch Dashboard에 비용 위젯 한 줄 더:
[1] 이번 달 누적 비용 (vs 지난달 같은 시점)
[2] 서비스별 (Fargate / RDS / Logs / NAT / ALB)
[3] 환경별 (env=prod vs env=staging vs env=dev)
[4] 일간 추세 (90일)
[5] Right Sizing 추천 수매주 한 번 oncall 회의에서 30분, 나빠지는 지표 조기 발견.
분담 책임: FinOps #
큰 조직은 FinOps라는 전담 영역이 따로 있어 비용을 보지만, 작은 조직에선 개발자 본인이 자기 모듈의 비용을 의식해야 합니다. 태그가 그래서 핵심입니다. 자기 코드의 청구서를 자기가 볼 수 있어야 의식이 생깁니다.
함정: 비용에서 자주 만나는 함정 #
1) 잠자는 다른 리전 자원 #
기초 #1의 함정 다시. AWS Resource Explorer 또는 Cost Explorer의 리전별 비용 → 0이 아닌 리전 점검.
2) terraform destroy 안 한 PoC
#
스택 / 환경을 만들고 잊는 실수. 태그 + 자동 청소 람다 패턴:
EventBridge schedule (매일 오전 9시)
│
▼
Lambda
- tag Project=PoC AND CreatedAt < 7 days ago
- 자원 삭제 / 알림3) Free Tier만료 모름 #
기초 #3의 결제 알림이 첫 방어선. + Cost Anomaly Detection으로 두 번째.
4) 100% Spot으로 운영 다운타임 #
Spot interruption이 한 번에 여러 task에 걸리면 service가 desired count를 못 채움 → 5xx 폭주. 항상 base on-demand.
5) Multi-AZ RDS 두 배 #
작은 시스템엔 Multi-AZ가 비용 부담. 그렇다고 단일 AZ도 곤란. 절충: dev/staging 단일 AZ + prod Multi-AZ.
6) VPC Endpoint 미사용 #
NAT만 쓰는 단순 셋업에서는 트래픽이 많은 자원(Logs, S3)이 NAT를 거쳐 비용이 폭주합니다. 운영에 들어가는 시점에 반드시 검토하세요.
7) 약정 후 아키텍처 변경 #
3년 약정을 체결한 직후 ARM이나 Lambda로 이전하면 약정 비용은 그대로 청구됩니다. 짧은 1년 약정부터, 아키텍처가 안정된 환경에서만 검토하세요.
AWS 트랙 27편 회고 #
이 트랙을 한 문장으로 묶으면:
“콘솔의 200개 서비스에서, 작은 백엔드를 안전하게 운영하는 데 필요한 도구상자만 추렸다.”
시리즈별 정리 #
| 시리즈 | 편수 | 무엇이 모였는가 |
|---|---|---|
| 기초 | 7 | 계정 / 리전 / IAM / 비용 / CLI / 보안 / 로그. 콘솔에 들어가기 전 지도 |
| 중급 | 7 | EC2 / VPC / S3 / RDS / Route 53 / ALB / CloudFront. 운영의 골격 |
| 고급 | 7 | ECS / ECR / Lambda / API Gateway / EventBridge / Secrets / Step Functions. 현대 백엔드의 핵심 |
| 실전 | 6 | 한 시스템으로. Fargate / RDS / CI/CD / IaC / 모니터링 / 비용 |
각 시리즈가 따로 있어도 한 축을 잡지만, 4 시리즈가 한 시스템으로 모이면 다른 그림이 됩니다. 비로소 운영 가능한 백엔드 한 벌이 갖춰집니다.
한 축에서 본 AWS의 본질 #
AWS는 서비스의 카탈로그가 아닙니다. 한 층 위에 다른 층을 쌓는 레고입니다.
┌─────────────────────────────────────┐
│ FinOps │ ← #6
│ 비용 / 태깅 / 약정 │
├─────────────────────────────────────┤
│ 관찰 가능성 │ ← #5
│ Logs / Metrics / Traces │
├─────────────────────────────────────┤
│ 자동화 │ ← #3, #4
│ CI/CD / IaC │
├─────────────────────────────────────┤
│ 데이터 │ ← #2 + 중급 #4
│ RDS / Secrets │
├─────────────────────────────────────┤
│ 컴퓨팅 │ ← #1 + 고급 #1~7
│ ECS / Lambda │
├─────────────────────────────────────┤
│ 네트워크 │ ← 중급 #1, 6, 7
│ VPC / ALB / CloudFront │
├─────────────────────────────────────┤
│ 컨트롤 평면 │ ← 기초 전체
│ 계정 / IAM / 비용 / 보안 │
└─────────────────────────────────────┘위 레이어를 거꾸로, 즉 컨트롤 → 네트워크 → 컴퓨팅 → 데이터 → 자동화 → 관찰 → FinOps가 운영의 자연스러운 진화 순서. 새 시스템을 만들 때마다 이 흐름을 다시 거치게 됩니다.
이 트랙이 다루지 않은 주제 #
다음 트랙으로 자연스럽게 이어지는 주제들:
- 컨테이너 표준화. Docker 트랙이 다음. 멀티스테이지 빌드 / 슬리밍 / 보안 스캔 / multi-arch, Fargate 위에 올라가는 이미지 자체를 깊이.
- Kubernetes. ECS의 다음 단계. 멀티 클러스터 / GitOps / 서비스 메시, 트래픽이 더 커지면 자연스러운 진화.
- 자격증. 같은 도메인을 시험 관점에서 다시 보는 흐름. 로드맵의 Cloud Practitioner / SAA / DVA 시리즈.
- DataOps / ML. Glue / SageMaker / Athena. 데이터가 많아지면 그쪽으로.
- 멀티 클라우드 / 하이브리드. Azure / GCP / on-prem과의 통합. 큰 조직에서 만나는 주제.
각 주제는 별도 트랙으로 다룰 가치가 있습니다.
트랙을 마무리하며 #
이 글까지 따라온 분이라면, AWS의 콘솔에서 무엇을 어디서 찾아야 하는지가 손에 붙었을 겁니다. 그게 이 트랙의 진짜 목표였습니다. 새 서비스 / 새 기능이 매년 추가되지만, 위 레이어 안의 어느 층인지 알면 새 도구도 빠르게 자리 잡습니다.
다음으로 권장 #
- Docker 트랙. 이 시리즈가 의존한 컨테이너 자체를 깊이. Multi-stage / 보안 / multi-arch / compose 까지 24편으로.
- 자격증: Cloud Practitioner / SAA / DVA. 같은 도구를 시험 관점에서 다시. 면접 / 이직 / 사내 평가에도 유용합니다.
- 자기 프로젝트. 글로 읽은 게 손에 붙는 가장 빠른 방법. 작은 사이드 프로젝트를 이 트랙의 패턴으로 한 번 띄워보세요. #1의 인프라가 거의 그대로 출발점이 됩니다.
긴 트랙을 따라와 주셔서 고맙습니다. AWS의 200개 서비스 카탈로그 앞에서 이제 두렵지 않은 상태, 모르는 도구가 나와도 “이건 컴퓨팅 레이어, 이건 네트워크 레이어"라는 위치 감각이 손에 붙은 상태에 서 있을 겁니다. 거기서부터가 진짜 운영의 시작이고, 이 트랙은 그 출발선까지 함께 걸은 여정입니다.
다음 트랙에서 또 만나뵙겠습니다.