클라우드 인프라 비용이 급격히 증가하면서 많은 기업들이 AWS 비용 최적화에 대한 고민을 하고 있습니다.
특히 EC2, S3, RDS는 AWS 청구서에서 가장 큰 비중을 차지하는 서비스들로, 이들 서비스의 비용 최적화는 전체 클라우드 비용 절감에 직접적인 영향을 미칩니다.
본 글에서는 실무에서 바로 적용할 수 있는 구체적인 AWS 비용 절감 방법과 모범 사례를 살펴보겠습니다.
AWS 비용 최적화가 중요한 이유
AWS 비용 최적화는 단순히 비용을 줄이는 것을 넘어서 효율적인 리소스 관리와 성능 향상까지 가져다줍니다.
많은 기업들이 클라우드 마이그레이션 초기에는 온프레미스와 동일한 방식으로 리소스를 프로비저닝하는 경우가 많습니다.
하지만 클라우드의 탄력성과 다양한 가격 모델을 활용하지 못하면 오히려 더 높은 비용을 지불하게 됩니다.
실제로 AWS 비용 최적화를 통해 30-50%의 비용 절감을 달성하는 기업들이 많습니다.
또한 적절한 리소스 크기 조정과 성능 튜닝을 통해 애플리케이션 성능도 함께 개선할 수 있습니다.
EC2 인스턴스 비용 최적화 전략
인스턴스 타입 최적화
EC2 인스턴스 비용 최적화의 첫 번째 단계는 워크로드에 맞는 적절한 인스턴스 타입을 선택하는 것입니다.
CPU 집약적인 애플리케이션이라면 C 시리즈를, 메모리 집약적이라면 R 시리즈를 선택해야 합니다.
# AWS CLI를 통한 인스턴스 사용률 모니터링
aws cloudwatch get-metric-statistics \
--namespace AWS/EC2 \
--metric-name CPUUtilization \
--dimensions Name=InstanceId,Value=i-1234567890abcdef0 \
--start-time 2024-01-01T00:00:00Z \
--end-time 2024-01-07T00:00:00Z \
--period 3600 \
--statistics Average
많은 기업들이 과도하게 큰 인스턴스를 사용하는 경우가 많습니다.
AWS Compute Optimizer를 활용하면 실제 사용률을 기반으로 최적의 인스턴스 타입을 추천받을 수 있습니다.
예약 인스턴스와 스팟 인스턴스 활용
장기간 실행되는 워크로드에는 예약 인스턴스(Reserved Instances)를 활용하여 최대 75%까지 비용을 절감할 수 있습니다.
1년 또는 3년 약정으로 예약 인스턴스를 구매하면 온디맨드 요금 대비 상당한 할인을 받을 수 있습니다.
# 예약 인스턴스 구매 최적화를 위한 Python 스크립트 예시
import boto3
from datetime import datetime, timedelta
def analyze_ri_recommendations():
client = boto3.client('ce') # Cost Explorer
response = client.get_rightsizing_recommendation(
service='Amazon Elastic Compute Cloud - Compute'
)
for recommendation in response['RightsizingRecommendations']:
print(f"Current Instance: {recommendation['CurrentInstance']}")
print(f"Recommended Action: {recommendation['RightsizingType']}")
print(f"Estimated Monthly Savings: ${recommendation['EstimatedMonthlySavings']}")
스팟 인스턴스는 온디맨드 요금의 최대 90%까지 할인된 가격으로 사용할 수 있습니다.
배치 처리, 개발 및 테스트 환경, 장애 허용 가능한 애플리케이션에 적합합니다.
자동 스케일링 구성
Auto Scaling을 통해 트래픽 패턴에 따라 인스턴스 수를 자동으로 조정할 수 있습니다.
# Auto Scaling 정책 예시 (CloudFormation)
AutoScalingGroup:
Type: AWS::AutoScaling::AutoScalingGroup
Properties:
MinSize: 2
MaxSize: 10
DesiredCapacity: 2
TargetGroupARNs:
- !Ref ALBTargetGroup
LaunchTemplate:
LaunchTemplateId: !Ref LaunchTemplate
Version: !GetAtt LaunchTemplate.LatestVersionNumber
ScaleUpPolicy:
Type: AWS::AutoScaling::ScalingPolicy
Properties:
AutoScalingGroupName: !Ref AutoScalingGroup
PolicyType: TargetTrackingScaling
TargetTrackingConfiguration:
TargetValue: 70.0
PredefinedMetricSpecification:
PredefinedMetricType: ASGAverageCPUUtilization
이를 통해 피크 시간대에는 인스턴스를 늘리고, 사용량이 적은 시간대에는 자동으로 줄여 비용을 최적화할 수 있습니다.
S3 스토리지 비용 최적화 방법
스토리지 클래스 최적화
S3 스토리지 비용 최적화의 핵심은 데이터 액세스 패턴에 따라 적절한 스토리지 클래스를 선택하는 것입니다.
자주 액세스하는 데이터는 Standard 클래스를, 가끔 액세스하는 데이터는 Standard-IA를 사용합니다.
# S3 스토리지 클래스 분석 및 최적화 스크립트
import boto3
from datetime import datetime, timedelta
def analyze_s3_storage_optimization():
s3 = boto3.client('s3')
cloudwatch = boto3.client('cloudwatch')
# 버킷별 스토리지 사용량 조회
buckets = s3.list_buckets()['Buckets']
for bucket in buckets:
bucket_name = bucket['Name']
# 지난 30일간 GET 요청 수 조회
response = cloudwatch.get_metric_statistics(
Namespace='AWS/S3',
MetricName='NumberOfObjects',
Dimensions=[
{
'Name': 'BucketName',
'Value': bucket_name
},
{
'Name': 'StorageType',
'Value': 'AllStorageTypes'
}
],
StartTime=datetime.now() - timedelta(days=30),
EndTime=datetime.now(),
Period=86400,
Statistics=['Average']
)
print(f"Bucket: {bucket_name}")
print(f"Average Objects: {response['Datapoints']}")
아카이브 데이터는 Glacier나 Glacier Deep Archive를 사용하여 최대 80%까지 비용을 절감할 수 있습니다.
수명 주기 정책 설정
S3 수명 주기 정책을 통해 데이터를 자동으로 다른 스토리지 클래스로 전환하거나 삭제할 수 있습니다.
{
"Rules": [
{
"ID": "OptimizeStorageClass",
"Status": "Enabled",
"Filter": {
"Prefix": "logs/"
},
"Transitions": [
{
"Days": 30,
"StorageClass": "STANDARD_IA"
},
{
"Days": 90,
"StorageClass": "GLACIER"
},
{
"Days": 365,
"StorageClass": "DEEP_ARCHIVE"
}
],
"Expiration": {
"Days": 2555
}
}
]
}
이러한 정책을 통해 자동으로 비용 효율적인 스토리지 클래스로 전환하여 S3 스토리지 비용을 대폭 절감할 수 있습니다.
멀티파트 업로드 및 압축 활용
대용량 파일은 멀티파트 업로드를 사용하여 업로드 효율성을 높이고, 압축을 통해 스토리지 비용을 줄일 수 있습니다.
# S3 멀티파트 업로드 및 압축 예시
import boto3
import gzip
import io
def upload_compressed_file(bucket_name, key, file_content):
s3 = boto3.client('s3')
# 파일 압축
compressed_data = io.BytesIO()
with gzip.GzipFile(fileobj=compressed_data, mode='wb') as gz:
gz.write(file_content.encode('utf-8'))
compressed_data.seek(0)
# 멀티파트 업로드
response = s3.create_multipart_upload(
Bucket=bucket_name,
Key=key,
ContentEncoding='gzip'
)
upload_id = response['UploadId']
# 파트별 업로드 (예시로 단일 파트)
part_response = s3.upload_part(
Bucket=bucket_name,
Key=key,
PartNumber=1,
UploadId=upload_id,
Body=compressed_data.getvalue()
)
# 멀티파트 업로드 완료
s3.complete_multipart_upload(
Bucket=bucket_name,
Key=key,
UploadId=upload_id,
MultipartUpload={
'Parts': [
{
'ETag': part_response['ETag'],
'PartNumber': 1
}
]
}
)
RDS 데이터베이스 비용 절감 기법
인스턴스 크기 최적화
RDS 비용 최적화의 첫 번째 단계는 데이터베이스 워크로드에 맞는 적절한 인스턴스 크기를 선택하는 것입니다.
CloudWatch 메트릭을 통해 CPU 사용률, 메모리 사용률, IOPS를 모니터링하여 최적의 인스턴스 타입을 결정할 수 있습니다.
# RDS 성능 메트릭 모니터링 스크립트
import boto3
from datetime import datetime, timedelta
def monitor_rds_performance(db_instance_identifier):
cloudwatch = boto3.client('cloudwatch')
metrics = ['CPUUtilization', 'DatabaseConnections', 'FreeableMemory']
for metric in metrics:
response = cloudwatch.get_metric_statistics(
Namespace='AWS/RDS',
MetricName=metric,
Dimensions=[
{
'Name': 'DBInstanceIdentifier',
'Value': db_instance_identifier
}
],
StartTime=datetime.now() - timedelta(days=7),
EndTime=datetime.now(),
Period=3600,
Statistics=['Average', 'Maximum']
)
print(f"Metric: {metric}")
for datapoint in response['Datapoints']:
print(f" Time: {datapoint['Timestamp']}")
print(f" Average: {datapoint['Average']}")
print(f" Maximum: {datapoint['Maximum']}")
지속적으로 낮은 사용률을 보이는 인스턴스는 더 작은 인스턴스 타입으로 다운그레이드하여 비용을 절감할 수 있습니다.
예약 인스턴스 활용
RDS에서도 예약 인스턴스를 통해 최대 60%까지 비용을 절감할 수 있습니다.
1년 또는 3년 약정으로 예약하면 상당한 할인 혜택을 받을 수 있습니다.
# AWS CLI를 통한 RDS 예약 인스턴스 구매
aws rds purchase-reserved-db-instances-offering \
--reserved-db-instances-offering-id 8ba30be1-b9ec-447d-9f19-7e4d2d87ca2f \
--reserved-db-instance-id myreservedinstance \
--db-instance-count 1
스토리지 최적화
RDS 스토리지 비용 최적화를 위해 gp3 볼륨 타입을 사용하고, 불필요한 스냅샷을 정기적으로 삭제해야 합니다.
# RDS 스냅샷 정리 자동화 스크립트
import boto3
from datetime import datetime, timedelta
def cleanup_old_snapshots(retention_days=7):
rds = boto3.client('rds')
# 자동 스냅샷 목록 조회
snapshots = rds.describe_db_snapshots(
SnapshotType='automated'
)['DBSnapshots']
cutoff_date = datetime.now() - timedelta(days=retention_days)
for snapshot in snapshots:
snapshot_date = snapshot['SnapshotCreateTime'].replace(tzinfo=None)
if snapshot_date < cutoff_date:
try:
rds.delete_db_snapshot(
DBSnapshotIdentifier=snapshot['DBSnapshotIdentifier']
)
print(f"Deleted snapshot: {snapshot['DBSnapshotIdentifier']}")
except Exception as e:
print(f"Error deleting snapshot: {e}")
읽기 전용 복제본 최적화
읽기 트래픽이 많은 애플리케이션의 경우 읽기 전용 복제본을 활용하여 주 데이터베이스의 부하를 분산시킬 수 있습니다.
하지만 불필요한 읽기 전용 복제본은 비용만 증가시키므로 실제 사용률을 모니터링하여 최적화해야 합니다.
통합 비용 모니터링 및 관리
AWS Cost Explorer 활용
AWS Cost Explorer를 통해 비용 트렌드를 분석하고 예산을 설정할 수 있습니다.
서비스별, 리전별, 태그별로 비용을 세분화하여 분석하면 비용 최적화 포인트를 쉽게 찾을 수 있습니다.
# Cost Explorer API를 활용한 비용 분석
import boto3
from datetime import datetime, timedelta
def analyze_monthly_costs():
ce = boto3.client('ce')
# 지난 6개월간 서비스별 비용 조회
response = ce.get_cost_and_usage(
TimePeriod={
'Start': (datetime.now() - timedelta(days=180)).strftime('%Y-%m-%d'),
'End': datetime.now().strftime('%Y-%m-%d')
},
Granularity='MONTHLY',
Metrics=['BlendedCost'],
GroupBy=[
{
'Type': 'DIMENSION',
'Key': 'SERVICE'
}
]
)
for result in response['ResultsByTime']:
print(f"Month: {result['TimePeriod']['Start']}")
for group in result['Groups']:
service = group['Keys'][0]
cost = group['Metrics']['BlendedCost']['Amount']
print(f" {service}: ${float(cost):.2f}")
예산 및 알림 설정
AWS Budgets를 통해 비용 예산을 설정하고 임계값을 초과할 때 알림을 받을 수 있습니다.
{
"BudgetName": "Monthly-EC2-Budget",
"BudgetLimit": {
"Amount": "1000",
"Unit": "USD"
},
"TimeUnit": "MONTHLY",
"TimePeriod": {
"Start": "2024-01-01",
"End": "2024-12-31"
},
"CostFilters": {
"Service": ["Amazon Elastic Compute Cloud - Compute"]
},
"BudgetType": "COST"
}
태그 기반 비용 관리
리소스에 일관된 태그를 적용하여 프로젝트별, 부서별, 환경별로 비용을 추적할 수 있습니다.
# 태그 기반 비용 분석
def analyze_costs_by_tags():
ce = boto3.client('ce')
response = ce.get_cost_and_usage(
TimePeriod={
'Start': (datetime.now() - timedelta(days=30)).strftime('%Y-%m-%d'),
'End': datetime.now().strftime('%Y-%m-%d')
},
Granularity='MONTHLY',
Metrics=['BlendedCost'],
GroupBy=[
{
'Type': 'TAG',
'Key': 'Environment'
}
]
)
for result in response['ResultsByTime']:
for group in result['Groups']:
environment = group['Keys'][0] if group['Keys'] else 'Untagged'
cost = group['Metrics']['BlendedCost']['Amount']
print(f"Environment {environment}: ${float(cost):.2f}")
실제 사례: 종합적인 비용 최적화 프로젝트
한 스타트업에서 월 AWS 비용이 $10,000에서 $4,000으로 60% 절감한 실제 사례를 살펴보겠습니다.
1단계: 현황 분석
먼저 Cost Explorer와 AWS Trusted Advisor를 통해 현재 비용 구조를 분석했습니다.
EC2가 전체 비용의 45%, S3가 25%, RDS가 20%를 차지하고 있었습니다.
2단계: EC2 최적화
과도하게 큰 인스턴스들을 적절한 크기로 조정하고, 개발 환경은 스팟 인스턴스로 전환했습니다.
또한 야간과 주말에는 자동으로 인스턴스를 중지하는 스케줄러를 구현했습니다.
# EC2 인스턴스 스케줄링 Lambda 함수
import boto3
import json
def lambda_handler(event, context):
ec2 = boto3.client('ec2')
# 개발 환경 태그가 있는 인스턴스 조회
instances = ec2.describe_instances(
Filters=[
{
'Name': 'tag:Environment',
'Values': ['dev', 'test']
},
{
'Name': 'instance-state-name',
'Values': ['running']
}
]
)
instance_ids = []
for reservation in instances['Reservations']:
for instance in reservation['Instances']:
instance_ids.append(instance['InstanceId'])
if instance_ids:
# 오후 6시에 인스턴스 중지
if event['action'] == 'stop':
ec2.stop_instances(InstanceIds=instance_ids)
print(f"Stopped instances: {instance_ids}")
# 오전 9시에 인스턴스 시작
elif event['action'] == 'start':
ec2.start_instances(InstanceIds=instance_ids)
print(f"Started instances: {instance_ids}")
return {
'statusCode': 200,
'body': json.dumps('Successfully processed instances')
}
3단계: S3 최적화
로그 파일과 아카이브 데이터를 Glacier로 이동하고, 수명 주기 정책을 설정하여 자동으로 관리하도록 했습니다.
또한 중복 파일을 제거하고 압축을 적용하여 스토리지 사용량을 줄였습니다.
4단계: RDS 최적화
과도하게 큰 RDS 인스턴스를 적절한 크기로 조정하고, 불필요한 스냅샷을 정리했습니다.
또한 프로덕션 데이터베이스에 대해 1년 예약 인스턴스를 구매했습니다.
결과
이러한 최적화를 통해 월 AWS 비용을 $10,000에서 $4,000으로 60% 절감했습니다.
EC2 비용은 70%, S3 비용은 50%, RDS 비용은 40% 감소했습니다.
동시에 애플리케이션 성능은 유지하면서 인프라 운영 효율성도 향상되었습니다.
지속적인 비용 최적화를 위한 모범 사례
정기적인 비용 검토
월별로 AWS 비용을 검토하고 트렌드를 분석하여 비정상적인 비용 증가를 조기에 발견해야 합니다.
각 서비스별로 비용 변화를 추적하고 원인을 파악하는 것이 중요합니다.
자동화된 비용 관리
수동으로 비용을 관리하는 것은 한계가 있으므로, 가능한 한 자동화된 도구와 스크립트를 활용해야 합니다.
AWS Lambda를 활용한 자동화된 리소스 관리와 정기적인 비용 리포트 생성이 효과적입니다.
팀 교육 및 문화 형성
개발팀과 운영팀 모두가 클라우드 비용에 대한 의식을 가져야 합니다.
정기적인 교육을 통해 비용 효율적인 아키텍처 설계와 리소스 사용 방법을 공유해야 합니다.
새로운 서비스 평가
AWS에서 새로운 서비스나 기능이 출시될 때마다 기존 아키텍처에 적용할 수 있는지 평가해야 합니다.
종종 새로운 서비스가 더 비용 효율적인 솔루션을 제공할 수 있습니다.
결론
AWS 비용 최적화는 일회성 작업이 아닌 지속적인 프로세스입니다.
EC2, S3, RDS 각 서비스의 특성을 이해하고 적절한 최적화 전략을 적용하면 상당한 비용 절감을 달성할 수 있습니다.
중요한 것은 비용 절감과 성능 유지 사이의 균형을 찾는 것입니다.
정기적인 모니터링과 분석을 통해 지속적으로 비용 효율성을 개선하고, 자동화된 도구를 활용하여 관리 부담을 줄이는 것이 성공적인 AWS 비용 최적화의 핵심입니다.
오늘 소개한 전략들을 단계적으로 적용하여 여러분의 AWS 비용을 효과적으로 관리해보시기 바랍니다.
'DevOps' 카테고리의 다른 글
Docker를 활용한 Spring Boot + Nginx 리버스 프록시 설정 완벽 가이드 (0) | 2025.05.24 |
---|---|
EC2와 GitHub Actions를 활용한 배포 파이프라인 구축: 효율적인 CI/CD 구현 가이드 (0) | 2025.05.24 |
AWS EC2 + RDS 배포 실전 가이드 - 비용 최적화까지 완벽 정리 (1) | 2025.05.05 |
Docker로 Spring Boot 애플리케이션 배포하기 - 실전용 Dockerfile 작성법 (0) | 2025.05.05 |
Backstage란? 개발팀을 위한 내부 개발 플랫폼(IDP) 완벽 가이드 (1) | 2025.03.12 |