우리 월 클라우드 비용이 왜 계속 올랐을까?
지난 4분기, AWS 월급이 갑자기 들뜬다는 Slack이 왔다. 9월 $12,400에서 11월 $17,200으로 38% 뛰었다. 비용 폭증 원인은 간단했다: 온디맨드 인스턴스로만 돌던 프로덕션 환경이 성장에 맞춰 무차별 확장되고 있었고, 개발/테스트 환경은 자정 이후에도 켜져만 있었다. 이 글은 그 과정을 회고하면서, 워크로드 특성에 따라 온디맨드·예약·스팟 인스턴스를 혼합하고, 태그 기반 비용 가시성과 자동 스케줄링으로 40~72% 절감을 달성한 실무 판단을 정리한 것이다.
- 핵심: 비용 절감은 아키텍처 선택의 그림자다. 개발 환경과 프로덕션을 다른 컴퓨트 유형으로 분리하고, 예약 인스턴스 커버리지를 70~80%로 맞춰야 한다.
- 수치: 예약 인스턴스 1년 약정으로 40~72% 절감, 스팟 인스턴스로 최대 90%, 그러나 SLA와 중단 리스크는 감수해야 한다.
- 실행: 태그 규칙 → 비용 대시보드 → Budget Alert → 자동 스케줄링. 이 순서로 접근해야 실제 절감이 나온다.
어디서 돈이 새고 있었나?
처음 의심은 간단했다. AWS Cost Explorer를 열었을 때 보인 건 **온디맨드 인스턴스 요금이 전체의 84%**였다. t3.medium 20개, m5.large 8개, c5.xlarge 4개—모두 시간당 가격 그대로 계산되고 있었다. 개발 환경의 m5.large 3개는 밤 10시부터 아침 6시까지 아무도 안 쓰는데 켜져만 있었다. 월 환산으로 $600이 낭비되는 셈이다.
컴퓨트 유형별 시간당 요금(us-east-1 기준, 2025년):
- t3.medium (온디맨드): $0.0416/시간 → 월 $30 (720시간)
- t3.medium (1년 예약): $0.0185/시간 → 월 $13.3 (55% 절감)
- t3.medium (스팟): $0.0125/시간 → 월 $9 (70% 절감, 단 중단 가능)
마찬가지로 프로덕션의 c5.xlarge는 트래픽 변동이 크지 않았다. 오전 9시~오후 6시가 피크고, 자정 이후는 30% 수준이었다. 평균 활용률이 45%인데 100% 용량을 항상 예약하고 있었다.
왜 이렇게 방치됐을까?
답은 "가시성이 없었다"는 것이었다. 청구서는 매달 왔지만, 어느 팀의 어느 환경이 얼마를 쓰는지 알 수 없었다. 백엔드 팀은 자기네 서버만 봤고, DevOps는 운영 비용을 프로젝트 단위로 보고할 방법이 없었다. 그래서 비용 최적화 논의도 추상적이었다: "클라우드가 비싸네"는 말뿐, 구체적 대상이 없었다.
AWS Cost Explorer는 있었지만, 조직 태그(Organization Tag) 규칙이 없었다. 리소스에 Environment: production, Team: backend, Project: api-v2 같은 태그가 붙어있지 않아, 비용을 그룹핑할 수 없었다. 가장 먼저 한 일이 태그 규칙을 수립하는 것이었다.
태그 규칙 정의:
Environment: {production, staging, development}
Team: {backend, frontend, infra, ml-training}
Project: {api-v2, realtime-feed, admin-panel, ...}
CostCenter: {engineering, research, ...}
3주 안에 태그 없는 인스턴스를 모두 정리하고, 신규 리소스는 IaC(Terraform) 레벨에 태그를 기본값으로 박았다. 그 순간부터 AWS Cost Explorer에서 Team별, Environment별 비용 분해가 가능했다.
컴퓨트 선택의 기준이 뭐였나?
태그로 가시성을 확보한 후, 환경별로 전략을 달리했다.
프로덕션: 예약 인스턴스로 기반 만들기
프로덕션은 안정성과 비용의 트레이드오프가 명확했다. 자체 로그와 메트릭 분석으로 지난 6개월 평균 활용률을 계산한 결과, c5.xlarge와 t3.medium의 기본 부하는 변하지 않았다. 따라서 **1년 약정 예약 인스턴스(Reserved Instance, RI)**로 전환했다.
AWS 공식 예약 인스턴스 가격 기준을 따르면, 1년 약정 RI는 온디맨드 대비 40~60% 할인을 받을 수 있다. 우리 경우:
- c5.xlarge 4개: $0.17/시간 × 720 × 12개월 × 4 (온디맨드) = $147,456/년 → 예약 시 $54,576/년 (63% 절감)
- t3.medium 20개: $0.0416/시간 × 720 × 12 × 20 (온디맨드) = $71,901/년 → 예약 시 $28,761/년 (60% 절감)
결과: 월 $12,400 → $8,300 (약 $4,100 절감). 하지만 리스크가 있었다. 6개월 뒤 마이크로서비스 아키텍처로 전환하면서 인스턴스 구성이 바뀔 가능성이 있었다. 그래서 **1년 풀 선결제 대신 1년 부분 선결제(Partial Upfront)**로 계약해, 필요시 Savings Plan으로 유연성을 살렸다.
개발/테스트: 스팟 인스턴스 + 스케줄링
개발 환경은 규칙적인 사용 패턴이 있었다. 업무 시간 내 4시간, 밤 10시부터 아침 6시까지는 끈다. 따라서 스팟 인스턴스 + 자동 스케줄링을 도입했다.
스팟 인스턴스는 AWS 스팟 가격에 따라 온디맨드 대비 최대 90% 저렴하다. m5.large는 온디맨드 $0.096/시간에서 스팟 $0.0288/시간 (70% 할인). 문제는 AWS가 2분 전 공지 후 언제든 중단할 수 있다는 점이다.
개발 환경이므로 중단이 치명적이지 않았다. 대신 StatefulSet 없는 무상태 서비스만 스팟으로 올렸다. 빌드 서버, 캐시, 임시 테스트 DB는 그대로 온디맨드로 두었다. 스팟이 중단되면 ECS Auto Scaling이 온디맨드로 자동 전환하는 Capacity Provider 정책을 썼다.
추가로 Lambda를 활용한 EventBridge 기반 자동 스케줄링을 구성했다:
# 밤 10시에 개발 환경 인스턴스 자동 종료
ScheduledAction:
- cron: "0 22 * * *" # 10 PM KST
action: "stop-dev-instances"
- cron: "0 6 * * 1-5" # 6 AM weekdays
action: "start-dev-instances"
결과: 개발 환경 비용 월 $1,200 → $240 (80% 절감). 단, 스팟 중단 사건이 월 1~2회 있었는데, 무상태 설계 덕분에 자동 재시작되었다.
숨은 비용도 봤나?
컴퓨트만 줄여도 충분하다고 생각했는데, Cost Explorer를 깊게 파니 또 다른 출혈이 있었다.
데이터 전송(Egress) 비용
리소스 간 데이터 전송이 월 $800을 차지했다. 특히 S3에서 EC2로 대량 다운로드하는 배치 작업, CloudFront 없이 직접 S3에서 서빙하는 정적 파일이 문제였다. S3 Standard → S3 Intelligent-Tiering 으로 전환하고, CloudFront 에지 로케이션을 캐시로 앞세웠다. Egress 비용은 월 $800 → $120으로 떨어졌다 (85% 절감).
스토리지 계층화
DB 스냅샷과 로그 아카이브가 S3 Standard에 쌓여있었다. 접근 빈도에 따라 계층화했다:
- 최근 30일: S3 Standard
- 30~90일: S3 Standard-IA (Infrequent Access)
- 90일 이상: S3 Glacier Flexible Retrieval
AWS S3 가격 기준으로 Glacier는 Standard 대비 80% 이상 저렴하다. 구현은 S3 Lifecycle Policy로 자동화했다. 스토리지 비용 월 $600 → $180으로 절감했다.
실제로 줄었나? 어떻게 확인했나?
4주 후 결과를 모았다.
| 항목 | 변경 전 | 변경 후 | 절감 |
|---|---|---|---|
| 프로덕션 컴퓨트 | $10,200 | $3,900 | 62% |
| 개발 컴퓨트 | $1,200 | $240 | 80% |
| 데이터 전송 | $800 | $120 | 85% |
| 스토리지 | $600 | $180 | 70% |
| 기타 | $600 | $400 | 33% |
| 합계 | $13,400 | $4,840 | 64% 절감 |
월 $8,560 절감. 연 $102,720이다. 이 수준은 우리 엔지니어 1명의 연봉 수준이었다.
다만 한 가지 실패가 있었다. 예약 인스턴스를 고르면서 너무 많이 예약해버렸다. 3개월 뒤 트래픽이 예상보다 적어서 예약한 c5.xlarge 2개가 유휴 상태가 됐다. 이번엔 Savings Plan(인스턴스 유형·크기 유연한 약정)으로 전환했다. Savings Plan 커버리지는 70~80% 목표로 조정했다. AWS FinOps 가이드에서 권장하는 "다음 분기 예산 편차 5% 이내"를 목표로 월 1회 리뷰를 시작했다.
같은 함정을 피하려면?
직접 겪어보니, 클라우드 비용 최적화는 기술보다 프로세스였다.
태그 규칙부터: 비용 가시성이 없으면 최적화할 대상을 모른다. 신규 리소스는 IaC에서 기본값으로 태그를 박되, 기존 리소스는 3주 내에 정리하고 태그 없는 것은 자동 중지하는 정책을 세운다.
워크로드를 먼저 분류: 안정적인 부하인지, 변동성이 크거나 중단 가능한지 판단하고, 그에 맞춰 컴퓨트 유형을 선택한다. 모든 것을 온디맨드로 두거나, 모든 것을 스팟으로 가는 건 둘 다 위험하다.
자동화 스케줄링: 개발/테스트 환경은 언제 켜고 꺼야 하는지 규칙을 코드로 정의하고, EventBridge/Lambda로 자동화한다. 수동으로는 절대 지켜지지 않는다.
예약 인스턴스는 신중하게: 1년 약정 전에 최근 6개월 사용 패턴을 분석하고, 확실한 기본 부하에만 예약한다. 불확실하면 Savings Plan으로 유연성을 산다.
숨은 비용을 찾는 습관: 컴퓨트만 봐선 부족하다. Egress, 스토리지 계층화, 미사용 탄력 IP·스냅샷을 월 1회는 정리한다.
핵심 정리
- 비용 절감의 기초는 가시성: 태그 규칙으로 부서·환경·프로젝트별 비용을 분해하지 않으면, 최적화할 대상이 없다.
- 컴퓨트 선택은 워크로드에: 안정적 부하는 예약 인스턴스(40~72% 절감), 변동성이 크거나 중단 가능한 작업은 스팟(최대 90%), 이벤트 기반은 서버리스. 혼합하는 게 정답이다.
- Egress와 스토리지도 챙겨야 한다: 컴퓨트만 40% 깎아도, 데이터 전송과 스토리지를 방치하면 실제 절감은 25~30% 수준에 그친다.
- 자동화 없으면 끝내는 것: 스케줄링, 태그 정리, Budget Alert는 코드로 구성하고, 월 1회 리뷰 프로세스를 정착시켜야 절감이 지속된다.
- 과도 예약의 함정: 초기 예약 인스턴스로 과도하게 약정하면, 나중에 유휴 리소스가 된다. Savings Plan이나 On-Demand Capacity Reservation으로 유연성을 확보하는 게 낫다.