DevFinance
테크·11 min read

AWS 비용 최적화 완전 가이드 2026 — EC2, S3, RDS 비용 절감 실전

AWS 비용이 예상보다 많이 나오는 개발자를 위한 최적화 가이드. EC2 Reserved Instance vs Savings Plans, S3 스토리지 클래스, RDS 비용 절감, 무료 티어 한도, 비용 모니터링 설정까지 실전 방법을 정리했습니다.

AWS 비용 — 모르면 청구서가 무섭다

AWS는 사용한 만큼 과금하는 구조라 설계를 잘못하면 예상보다 10배 이상 나오기도 합니다. 사이드 프로젝트부터 스타트업까지, 비용 구조를 이해하고 최적화하면 같은 성능을 30~70% 비용으로 운영할 수 있습니다.


AWS 비용 구조 이해

과금 주요 요소

서비스과금 기준주의 사항
EC2인스턴스 타입 × 시간중지해도 EBS 스토리지 과금
RDS인스턴스 타입 × 시간 + 스토리지Multi-AZ = 2배 비용
S3스토리지 GB + 요청 수 + 데이터 전송GET 요청도 과금됨
Lambda요청 수 + GB-초월 100만 건 무료
CloudFront데이터 전송 + 요청 수S3보다 저렴한 경우 많음
NAT Gateway시간 + GB개발 환경의 숨은 비용 주범
데이터 전송리전 간, 인터넷 아웃리전 내 동일 VPC는 무료

무료 티어 범위 (신규 계정 12개월)

서비스무료 한도
EC2t2.micro 750시간/월 (Linux/Windows)
RDSt2.micro 750시간/월 (MySQL, PostgreSQL 등)
S35GB 스토리지, 20,000 GET, 2,000 PUT 요청
CloudFront1TB 데이터 전송, 10,000,000 HTTP 요청
Lambda100만 요청/월, 400,000 GB-초 (영구 무료)
DynamoDB25GB 스토리지, 25 WCU/RCU (영구 무료)

EC2 비용 최적화

인스턴스 구매 옵션 비교

옵션할인율조건적합한 경우
On-Demand0%언제든 중지개발, 테스트
Savings Plans최대 72%1~3년 약정 (유연)상시 운영 서버
Reserved Instance최대 75%1~3년 약정 (고정)인스턴스 타입 변경 없을 때
Spot Instance최대 90%언제든 중단 가능배치 작업, CI/CD
Graviton (ARM)~20%ARM 아키텍처대부분의 워크로드

Savings Plans 설정

# AWS CLI로 Savings Plans 구매 권장사항 확인
aws ce get-savings-plans-purchase-recommendation \
  --savings-plans-type COMPUTE_SP \
  --term-in-years ONE_YEAR \
  --payment-option NO_UPFRONT \
  --lookback-period-in-days THIRTY_DAYS

개발 환경 인스턴스 자동 중지 (EventBridge)

# Lambda 함수: 평일 오전 9시 시작, 오후 7시 중지
import boto3

def lambda_handler(event, context):
    ec2 = boto3.client('ec2', region_name='ap-northeast-2')
    action = event.get('action', 'stop')
    
    # 태그로 관리 대상 인스턴스 필터링
    instances = ec2.describe_instances(
        Filters=[
            {'Name': 'tag:Environment', 'Values': ['dev']},
            {'Name': 'tag:AutoStop', 'Values': ['true']},
        ]
    )
    
    instance_ids = [
        i['InstanceId']
        for r in instances['Reservations']
        for i in r['Instances']
    ]
    
    if not instance_ids:
        return {'message': 'No instances found'}
    
    if action == 'start':
        ec2.start_instances(InstanceIds=instance_ids)
    else:
        ec2.stop_instances(InstanceIds=instance_ids)
    
    return {'action': action, 'instances': instance_ids}
# EventBridge 스케줄 (CDK/CloudFormation)
StartDevInstances:
  Type: AWS::Events::Rule
  Properties:
    ScheduleExpression: "cron(0 0 ? * MON-FRI *)"  # UTC 00:00 = KST 09:00
    Targets:
      - Arn: !GetAtt AutoStopLambda.Arn
        Input: '{"action": "start"}'

StopDevInstances:
  Type: AWS::Events::Rule
  Properties:
    ScheduleExpression: "cron(0 10 ? * MON-FRI *)"  # UTC 10:00 = KST 19:00
    Targets:
      - Arn: !GetAtt AutoStopLambda.Arn
        Input: '{"action": "stop"}'

절감 효과: 평일 10시간만 사용 → 월 최대 70% 절감 (168시간 → 50시간)

Graviton 인스턴스 전환

# 동일 성능 대비 약 20% 저렴
# x86 → ARM 전환 예시
# m5.large ($0.096/h) → m6g.large ($0.077/h)

# Amazon Linux 2023, Ubuntu 22.04+ ARM 이미지로 교체
# 대부분의 Node.js, Python, Go, Java 앱은 재컴파일 불필요

S3 비용 최적화

스토리지 클래스 비교

클래스GB당 월 비용접근 패턴복원 시간
Standard$0.023자주즉시
Intelligent-Tiering$0.023 (모니터링 $0.0025/객체)불규칙즉시
Standard-IA$0.0125월 1회 미만즉시
Glacier Instant$0.004분기 1회 미만즉시
Glacier Flexible$0.0036연 1~2회수 시간
Glacier Deep Archive$0.00099거의 없음12시간+

Lifecycle 정책 설정 (권장)

{
  "Rules": [
    {
      "Id": "archive-old-objects",
      "Status": "Enabled",
      "Transitions": [
        {
          "Days": 30,
          "StorageClass": "STANDARD_IA"
        },
        {
          "Days": 90,
          "StorageClass": "GLACIER_IR"
        },
        {
          "Days": 365,
          "StorageClass": "DEEP_ARCHIVE"
        }
      ],
      "Expiration": {
        "Days": 2555
      }
    },
    {
      "Id": "delete-incomplete-multipart",
      "Status": "Enabled",
      "AbortIncompleteMultipartUpload": {
        "DaysAfterInitiation": 7
      }
    }
  ]
}
# AWS CLI로 Lifecycle 정책 적용
aws s3api put-bucket-lifecycle-configuration \
  --bucket my-bucket \
  --lifecycle-configuration file://lifecycle.json

CloudFront로 S3 요청 비용 절감

S3 직접 접근: GET 요청 $0.0004/1,000건 + 데이터 전송 $0.09/GB
CloudFront 캐싱 후: 캐시 히트 요청은 S3 과금 없음 + 전송 $0.0085/GB

정적 사이트 월 10만 GET, 10GB 전송 기준:
S3 직접: $0.04 + $0.90 = $0.94
CloudFront + S3: $0.0085 × 10 = $0.085 (캐시 히트율 80% 기준)

RDS 비용 최적화

개발 환경 Multi-AZ 제거

# Multi-AZ 비활성화 (콘솔 또는 CLI)
aws rds modify-db-instance \
  --db-instance-identifier my-dev-db \
  --no-multi-az \
  --apply-immediately

# 비용 절감: 즉시 50% 감소
# 단, 프로덕션에서는 Multi-AZ 반드시 유지

Aurora Serverless v2 전환

# CloudFormation: Aurora Serverless v2
RDSCluster:
  Type: AWS::RDS::DBCluster
  Properties:
    Engine: aurora-postgresql
    EngineVersion: "15.4"
    ServerlessV2ScalingConfiguration:
      MinCapacity: 0.5   # 최소 0.5 ACU (~$0.06/h)
      MaxCapacity: 4     # 최대 4 ACU (트래픽에 따라 자동 조정)
Aurora Serverless v2 vs 상시 RDS 비교:
db.t3.medium 상시 운영: $0.068/h × 730h = $49.6/월
Aurora Serverless v2 (하루 4시간 집중):
  - 활성: 2 ACU × 4h × 30일 = $21.6
  - 유휴: 0.5 ACU × 20h × 30일 = $18.0
  = 약 $39.6/월 (20% 절감, 가변 트래픽일수록 절감 폭 증가)

RDS 스냅샷 관리

# 30일 이상 된 수동 스냅샷 목록
aws rds describe-db-snapshots \
  --snapshot-type manual \
  --query 'DBSnapshots[?SnapshotCreateTime<=`2026-03-01`].[DBSnapshotIdentifier,SnapshotCreateTime]' \
  --output table

# 스냅샷 삭제
aws rds delete-db-snapshot \
  --db-snapshot-identifier old-snapshot-id

NAT Gateway — 숨은 비용 주범

NAT Gateway는 가장 과소평가되는 비용 항목 중 하나입니다.

NAT Gateway 비용:
- 시간당 $0.059 × 730h = 약 $43/월 (고정)
- 처리 데이터 GB당 $0.059 추가

개발 환경에서 NAT Gateway 1개 = 월 $50+ 기본

대안: NAT Instance (저비용)

# NAT Instance 설정 (t4g.nano: ~$3/월)
# 커뮤니티 AMI 'amzn-ami-vpc-nat' 사용

# 소스/대상 확인 비활성화 (필수)
aws ec2 modify-instance-attribute \
  --instance-id i-xxxxx \
  --no-source-dest-check

# 라우팅 테이블: 0.0.0.0/0 → NAT Instance ID

대안: VPC Endpoint (S3, DynamoDB)

# S3 VPC Gateway Endpoint (무료)
# Private 서브넷에서 S3 접근 시 NAT Gateway 우회
aws ec2 create-vpc-endpoint \
  --vpc-id vpc-xxxxx \
  --service-name com.amazonaws.ap-northeast-2.s3 \
  --route-table-ids rtb-xxxxx

비용 모니터링 설정

AWS Budgets 알림

# CLI로 월 $50 예산 설정
aws budgets create-budget \
  --account-id 123456789012 \
  --budget '{
    "BudgetName": "monthly-cost-alert",
    "BudgetLimit": {"Amount": "50", "Unit": "USD"},
    "TimeUnit": "MONTHLY",
    "BudgetType": "COST"
  }' \
  --notifications-with-subscribers '[{
    "Notification": {
      "NotificationType": "ACTUAL",
      "ComparisonOperator": "GREATER_THAN",
      "Threshold": 80
    },
    "Subscribers": [{
      "SubscriptionType": "EMAIL",
      "Address": "your@email.com"
    }]
  }]'

Cost Anomaly Detection (이상 탐지)

# 이상 감지 모니터 생성
aws ce create-anomaly-monitor \
  --anomaly-monitor '{
    "MonitorName": "ServiceMonitor",
    "MonitorType": "DIMENSIONAL",
    "MonitorDimension": "SERVICE"
  }'

# 이상 감지 구독 ($10 초과 시 이메일)
aws ce create-anomaly-subscription \
  --anomaly-subscription '{
    "SubscriptionName": "AlertOver10",
    "MonitorArnList": ["arn:aws:ce::..."],
    "Subscribers": [{
      "Address": "your@email.com",
      "Type": "EMAIL"
    }],
    "Threshold": 10,
    "Frequency": "IMMEDIATE"
  }'

AWS Cost Explorer 활용

# 서비스별 지난 30일 비용 조회
aws ce get-cost-and-usage \
  --time-period Start=2026-03-10,End=2026-04-10 \
  --granularity MONTHLY \
  --metrics BlendedCost \
  --group-by Type=DIMENSION,Key=SERVICE \
  --query 'ResultsByTime[0].Groups[*].[Keys[0],Metrics.BlendedCost.Amount]' \
  --output table

서비스별 절감 체크리스트

EC2

□ 미사용 인스턴스 중지 또는 종료
□ 개발 환경 인스턴스 자동 중지 스케줄 설정
□ 상시 운영 인스턴스 Savings Plans 또는 RI 전환
□ Graviton 인스턴스로 교체 (ARM 호환 확인)
□ 미사용 EBS 볼륨(스냅샷 포함) 삭제
□ Elastic IP 미사용 시 즉시 해제 (과금됨)

S3

□ Lifecycle 정책으로 오래된 객체 자동 이전
□ Intelligent-Tiering 적용 (불규칙 액세스 패턴)
□ Incomplete multipart upload 자동 삭제 (7일)
□ CloudFront 캐싱으로 직접 요청 감소
□ 버전 관리 활성화 버킷의 이전 버전 정리
□ S3 Server Access Logging 대상 버킷 확인

RDS

□ 개발/스테이징 환경 Multi-AZ 비활성화
□ 사용하지 않는 RDS 인스턴스 중지 또는 삭제
□ 상시 운영 DB Reserved Instance 구매 검토
□ 오래된 스냅샷 정리
□ Aurora Serverless v2 전환 검토 (가변 트래픽)
□ 스토리지 자동 확장 임계값 적절히 설정

기타

□ NAT Gateway → NAT Instance 교체 검토 (개발 환경)
□ VPC Gateway Endpoint (S3, DynamoDB) 활성화
□ CloudWatch 로그 보존 기간 설정 (기본값: 무기한)
□ 미사용 Elastic Load Balancer 삭제
□ AWS Budgets 월별 알림 설정
□ Cost Anomaly Detection 활성화

비용 최적화 효과 요약

방법예상 절감난이도
개발 환경 인스턴스 자동 중지50~70%쉬움
Savings Plans 1년 약정30~40%쉬움
Graviton 전환20%쉬움
S3 Lifecycle 정책40~80% (저빈도 데이터)쉬움
NAT Gateway → NAT Instance$40~100/월중간
RDS Multi-AZ 개발 환경 제거50%쉬움
Aurora Serverless v2 전환20~60% (가변 트래픽)중간
CloudFront 캐싱 추가30~70% (S3 요청)중간

관련 글: Kubernetes 입문 완전 가이드 · Docker 입문 완전 가이드 · GitHub Actions CI/CD 설정법