AWS 실전 #6 비용 최적화와 대시보드: 트랙 마무리

9 분 소요

#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 / Egress10~20%자주 잊히는 비용 항목
ALB / 트래픽5~10%시간 + LCU
CloudWatch Logs / Metrics5~10%retention 누락 시 폭주
S3 / ECR2~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=SERVICE

Cost 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 / 메모리 사용률을 보고 작업 크기를 조정합니다.

Right Sizing의 예시
현재: 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으로:

capacity provider strategy
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 빌드 가능하면 굳이 안 쓸 이유가 없습니다.

Multi-arch 빌드
# 빌드
docker buildx build --platform linux/amd64,linux/arm64 \
  -t $REPO/blog-api:v1 --push .
Fargate ARM 64
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. 모든 그룹에 적용:

Terraform으로 일괄 30일
resource "aws_cloudwatch_log_group" "ecs" {
  for_each          = toset(["/ecs/blog-api", "/ecs/blog-api-migrate"])
  name              = each.key
  retention_in_days = 30
}

S3 #

오래된 객체를 자동으로 저렴한 클래스로:

S3 lifecycle
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 #

오래된 이미지를 자동 삭제:

ECR lifecycle
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.

NAT Gateway 비용
시간당  $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 한 줄 #

ECR Interface 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"
    }
  }
}

providerdefault_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 / 보안 / 로그. 콘솔에 들어가기 전 지도
중급7EC2 / VPC / S3 / RDS / Route 53 / ALB / CloudFront. 운영의 골격
고급7ECS / 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의 콘솔에서 무엇을 어디서 찾아야 하는지가 손에 붙었을 겁니다. 그게 이 트랙의 진짜 목표였습니다. 새 서비스 / 새 기능이 매년 추가되지만, 위 레이어 안의 어느 층인지 알면 새 도구도 빠르게 자리 잡습니다.

다음으로 권장 #

  1. Docker 트랙. 이 시리즈가 의존한 컨테이너 자체를 깊이. Multi-stage / 보안 / multi-arch / compose 까지 24편으로.
  2. 자격증: Cloud Practitioner / SAA / DVA. 같은 도구를 시험 관점에서 다시. 면접 / 이직 / 사내 평가에도 유용합니다.
  3. 자기 프로젝트. 글로 읽은 게 손에 붙는 가장 빠른 방법. 작은 사이드 프로젝트를 이 트랙의 패턴으로 한 번 띄워보세요. #1의 인프라가 거의 그대로 출발점이 됩니다.

긴 트랙을 따라와 주셔서 고맙습니다. AWS의 200개 서비스 카탈로그 앞에서 이제 두렵지 않은 상태, 모르는 도구가 나와도 “이건 컴퓨팅 레이어, 이건 네트워크 레이어"라는 위치 감각이 손에 붙은 상태에 서 있을 겁니다. 거기서부터가 진짜 운영의 시작이고, 이 트랙은 그 출발선까지 함께 걸은 여정입니다.

다음 트랙에서 또 만나뵙겠습니다.

X