본 콘텐츠의 이미지 및 내용은 AI로 생성되었습니다.
본 콘텐츠의 이미지 및 내용을 무단으로 복제, 배포, 수정하여 사용할 경우 저작권법에 의해 법적 제재를 받을 수 있습니다.
이미지 로딩 중...
AI Generated
2025. 12. 24. · 3 Views
AWS 리소스 정리와 비용 관리 완벽 가이드
AWS 사용 후 리소스를 안전하게 정리하고 예상치 못한 과금을 방지하는 방법을 배웁니다. 프리티어 관리부터 비용 모니터링까지 실무에서 꼭 필요한 내용을 다룹니다.
목차
- AWS 리소스 삭제 순서와 주의사항
- EC2, RDS, ELB 안전하게 종료하기
- 비용 탐색기(Cost Explorer) 활용
- 청구 알림(Billing Alert) 설정
- 프리티어 사용량 모니터링
- 예상치 못한 과금 방지 팁
1. AWS 리소스 삭제 순서와 주의사항
김신입 씨는 AWS 프리티어로 토이 프로젝트를 마친 후 리소스를 정리하려고 했습니다. EC2 인스턴스를 먼저 삭제했는데, 다음 달 청구서에 예상치 못한 요금이 청구되었습니다.
"분명 다 지웠는데 왜 요금이 나올까요?" 당황한 김신입 씨는 선배 개발자에게 달려갔습니다.
AWS 리소스 삭제 순서는 서로 의존 관계에 있는 리소스들을 올바른 순서로 제거하는 것을 의미합니다. 마치 레고 블록을 분해할 때 위에서부터 차례대로 떼어내야 하는 것처럼, AWS 리소스도 의존성을 고려하여 순서대로 삭제해야 합니다.
잘못된 순서로 삭제하면 일부 리소스가 남아 지속적으로 과금될 수 있습니다.
다음 코드를 살펴봅시다.
# AWS CLI를 사용한 안전한 리소스 정리 순서 확인
import boto3
# 현재 실행 중인 모든 리소스 조회
def check_all_resources(region='ap-northeast-2'):
ec2 = boto3.client('ec2', region_name=region)
# EC2 인스턴스 확인
instances = ec2.describe_instances()
print(f"실행 중인 EC2 인스턴스: {len(instances['Reservations'])}")
# EBS 볼륨 확인 (인스턴스 삭제 후에도 남을 수 있음)
volumes = ec2.describe_volumes(Filters=[{'Name': 'status', 'Values': ['available']}])
print(f"분리된 EBS 볼륨: {len(volumes['Volumes'])}")
# Elastic IP 확인 (연결 해제된 IP는 과금됨)
addresses = ec2.describe_addresses()
print(f"할당된 Elastic IP: {len(addresses['Addresses'])}")
김신입 씨는 첫 AWS 프로젝트를 마치고 뿌듯한 마음으로 리소스 정리를 시작했습니다. EC2 콘솔에 들어가 인스턴스를 종료하고 "이제 다 끝났다!"라고 생각했습니다.
하지만 한 달 후 받은 청구서에는 예상치 못한 20달러의 요금이 찍혀 있었습니다. 당황한 김신입 씨는 선배 개발자인 이멘토 씨를 찾아갔습니다.
"선배님, EC2도 다 껐고 RDS도 삭제했는데 왜 요금이 나올까요?" 이멘토 씨는 빙그레 웃으며 대답했습니다. "리소스 삭제도 순서가 있어요.
집을 철거할 때도 순서가 있잖아요?" AWS 리소스의 의존성이란 무엇일까요? 쉽게 비유하자면, AWS 리소스는 마치 조립식 가구와 같습니다.
책상 위에 모니터가 있다면 책상부터 치우면 모니터가 바닥에 떨어지겠죠? AWS도 마찬가지입니다.
로드 밸런서는 EC2 인스턴스를 참조하고, EC2 인스턴스는 EBS 볼륨과 보안 그룹을 사용합니다. 이런 관계를 이해하지 못하면 리소스가 고아처럼 남게 됩니다.
무작정 리소스를 삭제하면 어떤 일이 벌어질까요? 가장 흔한 실수는 EC2 인스턴스만 종료하고 끝내는 것입니다.
하지만 인스턴스에 연결된 EBS 볼륨은 자동으로 삭제되지 않을 수 있습니다. 볼륨 설정에서 "Delete on Termination"이 비활성화되어 있다면, 볼륨은 그대로 남아서 시간당 요금을 계속 부과합니다.
또한 Elastic IP를 할당만 해두고 인스턴스에 연결하지 않으면 시간당 요금이 발생합니다. 더 큰 문제는 스냅샷과 AMI입니다.
백업을 위해 생성한 스냅샷을 삭제하지 않으면 저장 용량만큼 계속 과금됩니다. AMI도 마찬가지입니다.
AMI를 삭제하더라도 연결된 스냅샷은 별도로 삭제해야 합니다. 그렇다면 올바른 삭제 순서는 무엇일까요?
첫 번째로, 애플리케이션 레벨부터 정리합니다. Load Balancer나 Auto Scaling Group처럼 다른 리소스를 참조하는 서비스를 먼저 제거해야 합니다.
로드 밸런서는 EC2 인스턴스를 참조하기 때문에 먼저 삭제하지 않으면 인스턴스 종료가 막힐 수 있습니다. 두 번째로, 컴퓨팅 리소스를 정리합니다.
EC2 인스턴스를 종료하고, RDS 데이터베이스를 삭제합니다. 이때 주의할 점은 "최종 스냅샷 생성" 옵션입니다.
정말 필요하지 않다면 이 옵션을 해제해야 불필요한 스냅샷 요금이 발생하지 않습니다. 세 번째로, 스토리지 리소스를 확인합니다.
EBS 볼륨 목록에서 "사용 가능(available)" 상태인 볼륨이 있다면 모두 삭제합니다. S3 버킷도 확인해야 합니다.
빈 버킷은 요금이 없지만, 데이터가 남아있다면 저장 용량만큼 과금됩니다. 네 번째로, 네트워크 리소스를 정리합니다.
Elastic IP는 할당만 해도 요금이 나오므로 반드시 릴리즈해야 합니다. VPC를 삭제하려면 먼저 NAT Gateway, Internet Gateway, 서브넷 등을 차례로 제거해야 합니다.
다섯 번째로, 백업과 스냅샷을 확인합니다. EC2 AMI를 삭제한 후 연결된 스냅샷도 별도로 삭제해야 합니다.
RDS 자동 백업은 인스턴스 삭제 시 함께 삭제되지만, 수동 스냅샷은 남아있으므로 주의해야 합니다. 위의 코드를 실행하면 현재 남아있는 리소스를 한눈에 확인할 수 있습니다.
먼저 boto3 클라이언트를 생성하여 특정 리전의 EC2 서비스에 접근합니다. describe_instances()로 실행 중인 인스턴스를 조회하고, describe_volumes()로 분리된 EBS 볼륨을 찾아냅니다.
describe_addresses()로 할당된 Elastic IP도 확인할 수 있습니다. 이렇게 하면 어떤 리소스가 남아서 과금되고 있는지 명확히 파악할 수 있습니다.
실제 현업에서는 어떻게 관리할까요? 많은 기업에서는 태그 기반 리소스 관리를 활용합니다.
프로젝트별로 "Project: MyApp", "Environment: Dev" 같은 태그를 붙여두면 나중에 한 번에 찾아서 삭제할 수 있습니다. 또한 AWS Resource Groups를 사용하면 특정 태그를 가진 모든 리소스를 그룹으로 묶어서 관리할 수 있습니다.
하지만 주의할 점도 있습니다. 초보 개발자들이 흔히 하는 실수 중 하나는 VPC를 먼저 삭제하려는 것입니다.
VPC 안에 서브넷, 라우팅 테이블, 인터넷 게이트웨이 등이 연결되어 있으면 삭제가 불가능합니다. 따라서 안쪽부터 차근차근 정리해야 합니다.
또한 CloudFormation 스택으로 생성한 리소스는 개별적으로 삭제하지 말고 스택 전체를 삭제해야 깔끔하게 정리됩니다. 다시 김신입 씨의 이야기로 돌아가 봅시다.
이멘토 씨의 설명을 들은 김신입 씨는 AWS 콘솔을 다시 열었습니다. EC2, EBS, Elastic IP, 스냅샷을 하나하나 확인하면서 남아있던 리소스를 모두 정리했습니다.
"이제야 제대로 정리한 것 같아요!" 리소스 삭제 순서를 제대로 이해하면 불필요한 비용을 절약하고 AWS 계정을 깔끔하게 관리할 수 있습니다. 여러분도 프로젝트가 끝난 후에는 체크리스트를 만들어서 하나씩 확인하는 습관을 들여보세요.
실전 팁
💡 - AWS CLI로 모든 리소스를 조회하는 스크립트를 만들어두면 누락 없이 정리할 수 있습니다
- CloudFormation이나 Terraform으로 인프라를 관리하면 한 번에 생성하고 삭제할 수 있어 편리합니다
- 비용이 의심된다면 Cost Explorer에서 "서비스별" 필터로 어디서 요금이 나오는지 확인하세요
2. EC2, RDS, ELB 안전하게 종료하기
박프로 씨는 개발 서버를 잠시 중단하려고 EC2 인스턴스를 "중지"했습니다. 하지만 며칠 후 청구서를 보니 여전히 요금이 발생하고 있었습니다.
"중지했는데 왜 요금이 나오죠?" 알고 보니 EBS 볼륨과 Elastic IP 때문이었습니다.
EC2, RDS, ELB 안전 종료는 각 서비스의 특성을 이해하고 과금 요소를 모두 제거하는 작업입니다. 마치 자동차 시동을 끌 때 라이트도 끄고 문도 잠그는 것처럼, AWS 서비스도 단순히 중지하는 것만으로는 부족합니다.
스토리지, 네트워크, 백업 등 연결된 모든 요소를 확인해야 완전히 종료할 수 있습니다.
다음 코드를 살펴봅시다.
import boto3
def safely_terminate_ec2(instance_id, region='ap-northeast-2'):
ec2 = boto3.client('ec2', region_name=region)
# 1. 인스턴스 정보 조회
response = ec2.describe_instances(InstanceIds=[instance_id])
instance = response['Reservations'][0]['Instances'][0]
# 2. Elastic IP 확인 및 해제
if 'PublicIpAddress' in instance:
addresses = ec2.describe_addresses(
Filters=[{'Name': 'instance-id', 'Values': [instance_id]}]
)
for addr in addresses['Addresses']:
ec2.release_address(AllocationId=addr['AllocationId'])
print(f"Elastic IP {addr['PublicIp']} 해제됨")
# 3. 인스턴스 종료 (EBS 자동 삭제 설정 확인)
ec2.terminate_instances(InstanceIds=[instance_id])
print(f"인스턴스 {instance_id} 종료 시작")
박프로 씨는 3년 차 백엔드 개발자입니다. 회사에서 개발 서버를 관리하고 있는데, 주말에는 사용하지 않으니 비용 절감을 위해 EC2 인스턴스를 중지하기로 했습니다.
AWS 콘솔에서 "중지" 버튼을 누르고 안심했습니다. 하지만 월요일에 출근해서 비용 리포트를 확인하니 주말에도 요금이 계속 나오고 있었습니다.
"분명 중지했는데 왜 요금이 나오지?" 당황한 박프로 씨는 클라우드 담당 최아키 씨에게 문의했습니다. "EC2를 중지해도 완전히 요금이 멈추는 건 아니에요." EC2 중지와 종료의 차이는 무엇일까요?
쉽게 비유하자면, EC2 인스턴스는 마치 렌탈카와 같습니다. **중지(Stop)**는 차를 주차장에 세워두는 것이고, **종료(Terminate)**는 차를 렌탈 회사에 완전히 반납하는 것입니다.
차를 주차장에 세워두면 주차 요금은 계속 나오겠죠? EC2도 마찬가지입니다.
중지하면 컴퓨팅 요금은 멈추지만 EBS 볼륨 요금은 계속 부과됩니다. 더 큰 함정은 Elastic IP입니다.
Elastic IP는 인스턴스에 연결되어 있을 때는 무료이지만, 인스턴스가 중지되거나 연결이 해제되면 시간당 요금이 발생합니다. 많은 개발자들이 이 사실을 모르고 불필요한 비용을 지불하고 있습니다.
RDS 데이터베이스는 어떻게 종료해야 할까요? RDS는 EC2보다 더 조심해야 합니다.
RDS 인스턴스를 삭제하면 기본적으로 최종 스냅샷을 생성하도록 설정되어 있습니다. 이 옵션을 그대로 두면 데이터베이스는 사라지지만 스냅샷이 남아서 저장 용량만큼 계속 과금됩니다.
정말로 데이터가 필요 없다면 "최종 스냅샷 건너뛰기"를 체크해야 합니다. 또한 RDS는 자동 백업과 수동 스냅샷을 구분해야 합니다.
자동 백업은 인스턴스 삭제 시 함께 삭제되지만, 수동으로 생성한 스냅샷은 별도로 삭제하지 않으면 영구히 남아있습니다. RDS 콘솔의 "스냅샷" 메뉴에서 불필요한 스냅샷을 모두 제거해야 합니다.
Load Balancer는 어떻게 정리할까요? Application Load Balancer(ALB)나 Network Load Balancer(NLB)는 시간당 요금이 부과됩니다.
사용하지 않는 로드 밸런서는 즉시 삭제해야 합니다. 하지만 로드 밸런서를 삭제하기 전에 **대상 그룹(Target Group)**을 먼저 확인해야 합니다.
대상 그룹 자체는 무료이지만, 여기에 연결된 EC2 인스턴스가 실행 중이라면 요금이 계속 나옵니다. Classic Load Balancer는 더 이상 권장되지 않지만 기존 프로젝트에 남아있을 수 있습니다.
이것도 시간당 요금이 부과되므로 사용하지 않는다면 바로 삭제하는 것이 좋습니다. 위의 코드는 EC2 인스턴스를 안전하게 종료하는 과정을 보여줍니다.
먼저 boto3 클라이언트로 EC2 서비스에 접근하고, describe_instances()로 인스턴스의 상세 정보를 가져옵니다. 그다음 describe_addresses()로 해당 인스턴스에 연결된 Elastic IP가 있는지 확인합니다.
만약 Elastic IP가 있다면 release_address()로 먼저 해제해야 불필요한 요금이 발생하지 않습니다. 마지막으로 terminate_instances()로 인스턴스를 종료합니다.
이때 중요한 것은 EBS 볼륨의 "Delete on Termination" 설정입니다. 인스턴스 생성 시 이 옵션이 활성화되어 있다면 인스턴스 종료와 함께 EBS 볼륨도 자동으로 삭제됩니다.
하지만 비활성화되어 있다면 볼륨이 남아서 계속 과금되므로, 인스턴스 종료 후 EBS 콘솔에서 "사용 가능(available)" 상태인 볼륨을 찾아 수동으로 삭제해야 합니다. 실제 현업에서는 어떻게 관리할까요?
많은 스타트업에서는 개발/테스트 환경을 자동으로 종료하는 Lambda 함수를 운영합니다. 매일 저녁 7시에 개발 서버를 자동으로 중지하고, 아침 9시에 다시 시작하는 방식입니다.
이렇게 하면 야간과 주말의 비용을 크게 절감할 수 있습니다. 물론 중지할 때 Elastic IP를 해제했다가 시작할 때 다시 할당하는 로직도 포함되어야 합니다.
하지만 주의할 점도 있습니다. 초보 개발자들이 흔히 하는 실수 중 하나는 프로덕션 환경과 개발 환경을 구분하지 않는 것입니다.
실수로 운영 서버를 종료하면 서비스 장애가 발생합니다. 따라서 반드시 태그를 활용하여 "Environment: Production"과 "Environment: Dev"를 명확히 구분하고, 자동화 스크립트에도 프로덕션 제외 로직을 넣어야 합니다.
또한 RDS 다중 AZ 배포를 사용 중이라면 대기 인스턴스도 함께 삭제됩니다. 하지만 읽기 전용 복제본(Read Replica)은 별도로 삭제해야 하므로 주의해야 합니다.
다시 박프로 씨의 이야기로 돌아가 봅시다. 최아키 씨의 조언을 들은 박프로 씨는 EC2 인스턴스를 종료하기 전에 Elastic IP를 먼저 해제했습니다.
그리고 EBS 볼륨도 함께 삭제되도록 설정을 확인했습니다. "이제야 제대로 된 종료 절차를 알았네요!" EC2, RDS, ELB를 안전하게 종료하려면 각 서비스의 과금 구조를 정확히 이해해야 합니다.
여러분도 리소스를 종료하기 전에 체크리스트를 만들어서 빠뜨리는 부분이 없는지 확인하는 습관을 들여보세요.
실전 팁
💡 - EC2를 중지할 때는 Elastic IP를 반드시 해제하여 불필요한 요금을 피하세요
- RDS 삭제 시 "최종 스냅샷 건너뛰기"를 체크하지 않으면 스냅샷 요금이 계속 발생합니다
- Lambda와 EventBridge를 조합하여 야간/주말에 자동으로 리소스를 중지하는 자동화를 구축하세요
3. 비용 탐색기(Cost Explorer) 활용
정주니어 씨는 이번 달 AWS 요금이 예상보다 두 배나 나왔습니다. "도대체 어디서 이렇게 많이 나온 거지?" 청구서를 열어봐도 복잡한 항목들만 나열되어 있어서 원인을 찾을 수 없었습니다.
선배가 "Cost Explorer를 사용해봐"라고 조언했습니다.
Cost Explorer는 AWS 비용을 시각화하고 분석할 수 있는 강력한 도구입니다. 마치 가계부 앱처럼 어디서 돈을 썼는지 그래프와 표로 보여줍니다.
서비스별, 리전별, 태그별로 비용을 분류하여 어떤 리소스가 가장 많은 비용을 발생시키는지 한눈에 파악할 수 있습니다.
다음 코드를 살펴봅시다.
import boto3
from datetime import datetime, timedelta
def analyze_monthly_cost():
ce = boto3.client('ce', region_name='us-east-1') # Cost Explorer는 us-east-1만 지원
# 이번 달 비용 조회
end_date = datetime.now().strftime('%Y-%m-%d')
start_date = (datetime.now() - timedelta(days=30)).strftime('%Y-%m-%d')
response = ce.get_cost_and_usage(
TimePeriod={'Start': start_date, 'End': end_date},
Granularity='DAILY',
Metrics=['UnblendedCost'],
GroupBy=[{'Type': 'DIMENSION', 'Key': 'SERVICE'}]
)
# 서비스별 비용 출력
for result in response['ResultsByTime']:
date = result['TimePeriod']['Start']
print(f"\n날짜: {date}")
for group in result['Groups']:
service = group['Keys'][0]
cost = float(group['Metrics']['UnblendedCost']['Amount'])
if cost > 0:
print(f" {service}: ${cost:.2f}")
정주니어 씨는 6개월 차 프론트엔드 개발자입니다. 회사에서 작은 토이 프로젝트를 AWS에 배포했는데, 이번 달 청구 금액이 80달러나 나왔습니다.
프리티어 범위 내에서 사용했다고 생각했는데 예상과 너무 다른 금액이었습니다. 청구서를 다운로드해서 엑셀로 열어봤지만 수백 개의 항목이 나열되어 있어서 도저히 이해할 수 없었습니다.
"EC2 데이터 전송", "RDS 스토리지", "S3 요청 횟수" 같은 용어들만 가득했습니다. 답답한 마음에 클라우드 전문가인 신시니어 씨를 찾아갔습니다.
"Cost Explorer를 사용하면 한눈에 보여요." Cost Explorer란 정확히 무엇일까요? 쉽게 비유하자면, Cost Explorer는 마치 신용카드 앱의 소비 분석 기능과 같습니다.
신용카드 앱에서 "식비에 30만원, 교통비에 10만원" 같이 카테고리별로 보여주는 것처럼, Cost Explorer도 "EC2에 40달러, RDS에 20달러, S3에 10달러" 같이 서비스별로 비용을 분류해서 보여줍니다. 그래프로 시각화되어 있어서 어느 서비스가 비용의 대부분을 차지하는지 직관적으로 알 수 있습니다.
왜 청구서만으로는 부족할까요? AWS 청구서는 매우 상세합니다.
모든 리소스의 사용 시간, 데이터 전송량, API 호출 횟수 등이 개별 항목으로 나열됩니다. 하지만 이런 세부 정보는 오히려 전체적인 그림을 보는 데 방해가 됩니다.
마치 나무만 보고 숲을 보지 못하는 상황이 되는 것입니다. 더 큰 문제는 예측하기 어렵다는 점입니다.
청구서는 이미 발생한 비용만 보여주기 때문에, 다음 달에 얼마나 나올지 가늠하기 어렵습니다. 프로젝트가 커지면서 비용이 갑자기 폭증하는 경우도 많습니다.
Cost Explorer의 핵심 기능은 무엇일까요? 첫 번째는 서비스별 분류입니다.
EC2, RDS, S3, Lambda 등 각 서비스가 얼마나 비용을 발생시키는지 한눈에 볼 수 있습니다. 정주니어 씨의 경우 EC2가 전체 비용의 70%를 차지하고 있었습니다.
두 번째는 시간대별 추이입니다. 일별, 주별, 월별로 비용 변화를 그래프로 보여줍니다.
갑자기 비용이 급증한 날짜가 있다면, 그날 무슨 일이 있었는지 추적할 수 있습니다. 정주니어 씨는 3주 전에 RDS 인스턴스를 db.t3.micro에서 db.t3.small로 업그레이드했고, 그 이후로 비용이 두 배로 늘어난 것을 발견했습니다.
세 번째는 태그 기반 분석입니다. 리소스에 "Project: WebApp", "Environment: Dev" 같은 태그를 붙여두면, 프로젝트별 또는 환경별로 비용을 분리할 수 있습니다.
개발 환경과 프로덕션 환경의 비용을 따로 추적하면 불필요한 개발 비용을 줄일 수 있습니다. 네 번째는 리전별 분석입니다.
서울 리전과 버지니아 리전의 비용을 비교하면, 어느 리전이 더 저렴한지 알 수 있습니다. 일부 서비스는 리전마다 가격이 다르기 때문에 리전 선택만 바꿔도 비용을 절감할 수 있습니다.
다섯 번째는 비용 예측입니다. 현재 추세를 기반으로 다음 달 예상 비용을 보여줍니다.
만약 예상 비용이 예산을 초과한다면 미리 대응할 수 있습니다. 위의 코드는 Python boto3를 사용하여 Cost Explorer API를 호출하는 방법을 보여줍니다.
먼저 boto3.client('ce')로 Cost Explorer 클라이언트를 생성합니다. 주의할 점은 Cost Explorer API는 us-east-1 리전에서만 사용할 수 있다는 것입니다.
다른 리전을 지정하면 에러가 발생합니다. get_cost_and_usage() 함수로 특정 기간의 비용을 조회합니다.
TimePeriod로 시작일과 종료일을 지정하고, Granularity로 일별(DAILY) 또는 월별(MONTHLY) 단위를 선택합니다. Metrics에는 'UnblendedCost'를 지정하여 실제 발생한 비용을 가져옵니다.
GroupBy로 서비스별로 그룹핑하면 각 서비스의 비용을 따로 볼 수 있습니다. 결과는 날짜별로 반환되며, 각 날짜마다 서비스 목록과 비용이 포함됩니다.
이 데이터를 가공하면 대시보드나 알림 시스템을 직접 구축할 수도 있습니다. 실제 현업에서는 어떻게 활용할까요?
많은 기업에서는 매주 월요일 아침에 Cost Explorer 리포트를 자동으로 생성하여 슬랙으로 전송합니다. 지난주 비용 요약, 가장 많이 증가한 서비스, 예상 월 비용 등을 포함합니다.
이렇게 하면 팀 전체가 비용을 인식하고 불필요한 리소스를 빠르게 정리할 수 있습니다. 또한 예산 알림과 결합하여 사용합니다.
Cost Explorer에서 예상 비용이 예산의 80%를 넘으면 경고 이메일을 발송하고, 90%를 넘으면 자동으로 개발 환경의 일부 리소스를 중지하는 방식입니다. 하지만 주의할 점도 있습니다.
초보 개발자들이 흔히 하는 실수 중 하나는 Cost Explorer 자체의 요금을 간과하는 것입니다. Cost Explorer는 기본 기능은 무료이지만, API를 통해 데이터를 가져오면 요청당 0.01달러가 부과됩니다.
하루에 100번 호출하면 한 달에 30달러가 나옵니다. 따라서 API 호출은 최소화하고, 결과를 캐싱하여 재사용하는 것이 좋습니다.
또한 태그가 없는 리소스는 분류가 어렵습니다. Cost Explorer를 최대한 활용하려면 모든 리소스에 일관된 태그 정책을 적용해야 합니다.
"Project", "Environment", "Owner" 같은 태그를 표준화하여 사용하면 나중에 분석이 훨씬 쉬워집니다. 다시 정주니어 씨의 이야기로 돌아가 봅시다.
신시니어 씨와 함께 Cost Explorer를 열어본 정주니어 씨는 눈이 번쩍 뜨였습니다. "EC2 인스턴스를 하나만 쓰는 줄 알았는데 Auto Scaling으로 세 개가 계속 돌아가고 있었네요!" 불필요한 Auto Scaling 설정을 제거하자 비용이 절반으로 줄어들었습니다.
Cost Explorer를 제대로 활용하면 비용의 숨은 원인을 빠르게 찾아낼 수 있습니다. 여러분도 매주 한 번씩 Cost Explorer를 확인하는 습관을 들여보세요.
실전 팁
💡 - Cost Explorer의 "저장된 보고서" 기능으로 자주 보는 필터를 저장해두면 편리합니다
- "일별 비용" 그래프에서 급증한 날짜를 찾으면 문제의 원인을 추적하기 쉽습니다
- 태그를 일관되게 적용하여 프로젝트별, 팀별 비용을 명확히 분리하세요
4. 청구 알림(Billing Alert) 설정
송학생 씨는 졸업 프로젝트로 AWS를 사용하다가 실수로 RDS 인스턴스를 db.m5.large로 생성했습니다. 한 달이 지나고 350달러의 청구서를 받고 깜짝 놀랐습니다.
"미리 알림을 받았더라면 일찍 발견했을 텐데..." 후회했지만 이미 늦었습니다.
Billing Alert는 AWS 비용이 특정 금액을 초과하면 자동으로 알림을 보내주는 기능입니다. 마치 신용카드 사용 알림처럼 실시간으로 비용을 모니터링하여 예산을 초과하기 전에 미리 경고해줍니다.
CloudWatch와 SNS를 결합하여 이메일, SMS, 슬랙 등 다양한 채널로 알림을 받을 수 있습니다.
다음 코드를 살펴봅시다.
import boto3
def create_billing_alert(budget_limit=10, email='your-email@example.com'):
# CloudWatch Alarm 생성 (us-east-1에서만 가능)
cloudwatch = boto3.client('cloudwatch', region_name='us-east-1')
sns = boto3.client('sns', region_name='us-east-1')
# SNS 토픽 생성
topic_response = sns.create_topic(Name='BillingAlerts')
topic_arn = topic_response['TopicArn']
# 이메일 구독 추가
sns.subscribe(
TopicArn=topic_arn,
Protocol='email',
Endpoint=email
)
# CloudWatch Alarm 설정
cloudwatch.put_metric_alarm(
AlarmName='MonthlyBillingAlert',
ComparisonOperator='GreaterThanThreshold',
EvaluationPeriods=1,
MetricName='EstimatedCharges',
Namespace='AWS/Billing',
Period=21600, # 6시간마다 체크
Statistic='Maximum',
Threshold=budget_limit,
ActionsEnabled=True,
AlarmActions=[topic_arn],
AlarmDescription=f'월 예상 비용이 ${budget_limit}를 초과했습니다'
)
print(f"청구 알림이 설정되었습니다. ${budget_limit} 초과 시 {email}로 알림 전송")
송학생 씨는 컴퓨터공학과 4학년 학생입니다. 졸업 프로젝트로 웹 애플리케이션을 만들면서 AWS 프리티어를 사용하기로 했습니다.
인터넷에서 찾은 튜토리얼을 따라 RDS 데이터베이스를 생성했는데, 인스턴스 타입을 잘못 선택했습니다. 프리티어는 db.t3.micro만 무료인데, 실수로 db.m5.large를 선택했습니다.
프로젝트에 집중하느라 AWS 콘솔을 확인하지 않았고, 한 달이 지나서야 청구서를 받고 깜짝 놀랐습니다. "350달러나 나왔어요!" 아르바이트로 번 돈을 모두 쓰게 된 송학생 씨는 속이 상했습니다.
친구인 나선배 씨에게 이 이야기를 하자, 나선배 씨가 말했습니다. "청구 알림을 설정해뒀으면 일찍 발견했을 텐데.
나는 5달러만 넘어도 알림이 와." Billing Alert란 정확히 무엇일까요? 쉽게 비유하자면, Billing Alert는 마치 통장 잔액 알림 서비스와 같습니다.
은행에서 잔액이 10만원 이하로 떨어지면 알림을 보내주는 것처럼, AWS도 비용이 특정 금액을 넘으면 즉시 알려줍니다. 이렇게 하면 문제가 커지기 전에 빠르게 대응할 수 있습니다.
AWS는 두 가지 방식으로 청구 알림을 제공합니다. 하나는 AWS Budgets이고, 다른 하나는 CloudWatch Billing Alarm입니다.
Budgets는 더 고급 기능을 제공하지만 예산당 월 0.02달러가 부과됩니다. CloudWatch Alarm은 첫 10개 알람까지 무료이므로 개인 프로젝트에 적합합니다.
왜 청구 알림이 중요할까요? AWS는 사용한 만큼 비용이 부과되는 종량제 모델입니다.
고정 요금제가 아니기 때문에 실수나 설정 오류로 예상치 못한 비용이 발생할 수 있습니다. 특히 Auto Scaling이나 Lambda 같은 서비스는 트래픽이 급증하면 비용도 함께 폭증합니다.
더 큰 문제는 악의적인 사용입니다. 만약 AWS 계정이 해킹당하면 공격자가 대량의 EC2 인스턴스를 생성하여 비트코인 채굴에 사용할 수 있습니다.
이런 경우 하루 만에 수천 달러의 비용이 발생할 수 있습니다. 청구 알림이 설정되어 있다면 몇 시간 내에 이상 징후를 감지하여 큰 피해를 막을 수 있습니다.
CloudWatch Billing Alarm 설정 방법은 어떻게 될까요? 먼저 AWS 콘솔에서 계정 설정으로 들어가 "청구 알림 수신"을 활성화해야 합니다.
이 설정을 켜지 않으면 CloudWatch에서 청구 데이터를 수집할 수 없습니다. 다음으로 SNS 토픽을 생성합니다.
SNS는 Simple Notification Service의 약자로, 알림을 전달하는 역할을 합니다. 토픽을 생성하고 이메일 주소를 구독자로 추가하면, 알람이 발생했을 때 이메일로 알림이 전송됩니다.
이메일을 추가하면 확인 메일이 오는데, 반드시 "Confirm Subscription"을 클릭해야 활성화됩니다. 마지막으로 CloudWatch Alarm을 생성합니다.
메트릭으로 "EstimatedCharges"를 선택하고, 임계값을 설정합니다. 예를 들어 10달러로 설정하면 예상 월 비용이 10달러를 넘는 순간 알림이 발송됩니다.
위의 코드는 Python boto3로 청구 알림을 자동 설정하는 방법을 보여줍니다. 먼저 SNS 클라이언트로 토픽을 생성하고, 이메일 주소를 구독자로 추가합니다.
그다음 CloudWatch 클라이언트로 알람을 생성합니다. MetricName은 'EstimatedCharges'로 지정하고, Namespace는 'AWS/Billing'을 사용합니다.
Threshold에 예산 한도를 설정하면, 이 금액을 초과할 때 AlarmActions로 지정된 SNS 토픽으로 알림이 전송됩니다. 주의할 점은 Billing 메트릭은 us-east-1 리전에서만 사용할 수 있다는 것입니다.
다른 리전에서는 데이터를 수집할 수 없으므로 반드시 us-east-1을 지정해야 합니다. 실제 현업에서는 어떻게 활용할까요?
많은 스타트업에서는 다단계 알림을 설정합니다. 예산이 100달러라면 50달러(50%), 80달러(80%), 100달러(100%)에서 각각 알림을 보내는 방식입니다.
50달러 알림은 정보 차원에서 슬랙으로 보내고, 80달러 알림은 팀 리더에게 이메일로 보내며, 100달러 알림은 긴급 SMS로 발송합니다. 또한 자동 대응을 결합하기도 합니다.
예산을 80% 초과하면 Lambda 함수가 자동으로 실행되어 개발 환경의 모든 EC2 인스턴스를 중지하는 방식입니다. 물론 프로덕션 환경은 제외해야 합니다.
하지만 주의할 점도 있습니다. 초보 개발자들이 흔히 하는 실수 중 하나는 임계값을 너무 낮게 설정하는 것입니다.
프리티어라도 약간의 비용은 발생할 수 있습니다. 예를 들어 S3에 데이터를 업로드하면 프리티어 한도를 초과하면서 몇 센트의 요금이 나올 수 있습니다.
임계값을 1달러로 설정하면 매일 알림이 와서 피로도만 높아집니다. 적절한 임계값은 프리티어의 경우 5~10달러 정도가 좋습니다.
또한 SNS 구독 확인을 잊어버리는 경우가 많습니다. 이메일로 확인 링크가 오는데 48시간 안에 클릭하지 않으면 구독이 취소됩니다.
알림을 설정했다고 안심했다가 실제로는 알림이 오지 않는 상황이 발생할 수 있습니다. 다시 송학생 씨의 이야기로 돌아가 봅시다.
나선배 씨의 도움으로 청구 알림을 설정한 송학생 씨는 이번에는 5달러, 10달러, 20달러 세 단계로 알림을 만들었습니다. "이제는 안심이에요.
조금만 이상해도 바로 알 수 있으니까요." 청구 알림은 AWS를 안전하게 사용하기 위한 필수 안전장치입니다. 여러분도 AWS를 시작하는 순간 가장 먼저 청구 알림을 설정하는 습관을 들여보세요.
실전 팁
💡 - SNS 이메일 구독 후 반드시 48시간 내에 확인 링크를 클릭해야 활성화됩니다
- 다단계 알림(50%, 80%, 100%)을 설정하여 문제를 조기에 감지하세요
- 슬랙 웹훅을 SNS와 연결하면 팀 전체가 실시간으로 비용을 모니터링할 수 있습니다
5. 프리티어 사용량 모니터링
최입문 씨는 AWS 프리티어로 공부를 시작했습니다. "12개월 무료니까 걱정 없겠지?"라고 생각했지만, 몇 달 후 예상치 못한 청구서를 받았습니다.
프리티어에도 한도가 있다는 사실을 뒤늦게 알게 되었습니다.
프리티어 사용량 모니터링은 AWS 무료 한도를 얼마나 사용했는지 추적하여 초과하기 전에 조치를 취하는 것입니다. 마치 휴대폰 데이터 사용량을 확인하는 것처럼, 프리티어 한도를 실시간으로 체크하여 예상치 못한 과금을 방지할 수 있습니다.
AWS는 대시보드와 API를 통해 프리티어 사용량을 상세히 제공합니다.
다음 코드를 살펴봅시다.
import boto3
from datetime import datetime, timedelta
def check_freetier_usage():
ce = boto3.client('ce', region_name='us-east-1')
# 이번 달 시작일과 오늘 날짜
today = datetime.now()
start_of_month = today.replace(day=1).strftime('%Y-%m-%d')
end_date = today.strftime('%Y-%m-%d')
# 프리티어 대상 서비스별 사용량 조회
response = ce.get_cost_and_usage(
TimePeriod={'Start': start_of_month, 'End': end_date},
Granularity='MONTHLY',
Metrics=['UsageQuantity'],
GroupBy=[{'Type': 'DIMENSION', 'Key': 'SERVICE'}],
Filter={
'Dimensions': {
'Key': 'RECORD_TYPE',
'Values': ['Usage']
}
}
)
# 주요 프리티어 한도
freetier_limits = {
'Amazon Elastic Compute Cloud': '750 hours/month',
'Amazon Relational Database Service': '750 hours/month',
'Amazon Simple Storage Service': '5 GB storage'
}
print("=== 프리티어 사용량 현황 ===")
for result in response['ResultsByTime']:
for group in result['Groups']:
service = group['Keys'][0]
if service in freetier_limits:
usage = group['Metrics']['UsageQuantity']
print(f"{service}: {usage['Amount']} {usage['Unit']}")
print(f" 한도: {freetier_limits[service]}\n")
최입문 씨는 백엔드 개발을 배우기 시작한 신입 개발자입니다. AWS 프리티어가 12개월 무료라는 광고를 보고 가입했습니다.
"12개월 동안 무료니까 마음껏 써도 되겠네!"라고 생각하며 EC2 인스턴스를 여러 개 실행했습니다. 3개월 후, 25달러의 청구서가 날아왔습니다.
"분명 프리티어인데 왜 요금이 나오지?" 당황한 최입문 씨는 AWS 지원팀에 문의했습니다. 답변은 간단했습니다.
"EC2 프리티어 한도는 월 750시간입니다. 인스턴스 3개를 동시에 실행하면 한 달에 2,250시간이 소모되므로 1,500시간이 초과됩니다." 멘토인 한고수 씨가 설명해주었습니다.
"프리티어는 무료이지만 무제한이 아니에요. 한도를 넘으면 일반 요금이 청구돼요." AWS 프리티어의 종류는 무엇일까요?
AWS 프리티어는 크게 세 가지로 나뉩니다. 첫 번째는 12개월 무료입니다.
가입 후 12개월 동안만 무료로 제공되며, EC2, RDS, S3 등이 포함됩니다. 두 번째는 상시 무료입니다.
Lambda 100만 요청, DynamoDB 25GB 저장 공간 등은 계정 나이와 관계없이 평생 무료입니다. 세 번째는 단기 무료 체험입니다.
Redshift, SageMaker 등 특정 서비스는 2개월 또는 3개월 동안만 무료로 제공됩니다. EC2 프리티어 한도는 어떻게 계산될까요?
EC2 프리티어는 월 750시간입니다. 쉽게 비유하자면, 마치 휴대폰 무료 통화 시간과 같습니다.
한 달은 약 730시간이므로 t2.micro 또는 t3.micro 인스턴스 하나를 24시간 내내 켜둘 수 있습니다. 하지만 인스턴스 두 개를 동시에 실행하면 한 달에 1,460시간이 소모되므로 710시간이 초과되어 요금이 부과됩니다.
더 큰 인스턴스 타입은 프리티어에 포함되지 않습니다. t2.small이나 t2.medium은 무료 한도가 없으므로 사용 시간 전체에 대해 요금이 부과됩니다.
많은 초보자들이 "EC2는 무료"라고 착각하여 큰 인스턴스를 실행했다가 놀라는 경우가 많습니다. RDS 프리티어 한도는 어떻게 될까요?
RDS도 EC2와 마찬가지로 월 750시간입니다. db.t2.micro 또는 db.t3.micro 인스턴스 하나를 한 달 내내 실행할 수 있습니다.
저장 공간은 20GB까지 무료이며, 백업과 스냅샷도 20GB까지 무료입니다. 하지만 다중 AZ 배포는 프리티어에 포함되지 않습니다.
다중 AZ를 활성화하면 대기 인스턴스가 추가로 생성되어 시간이 두 배로 소모됩니다. S3 프리티어 한도는 어떻게 될까요?
S3는 12개월 동안 5GB 저장 공간, 20,000건의 GET 요청, 2,000건의 PUT 요청이 무료입니다. 저장 공간은 넉넉해 보이지만 GET 요청 횟수를 주의해야 합니다.
웹사이트에서 이미지를 S3에서 직접 로딩한다면 트래픽이 많을 때 20,000건을 쉽게 초과할 수 있습니다. 이런 경우 CloudFront(CDN)를 앞에 두면 S3 요청을 줄일 수 있습니다.
Lambda 프리티어 한도는 평생 무료입니다. Lambda는 상시 무료 항목으로, 매월 100만 요청과 40만 GB-초의 컴퓨팅 시간이 무료입니다.
GB-초는 메모리와 실행 시간을 곱한 값입니다. 예를 들어 128MB 메모리로 설정된 Lambda가 3초 동안 실행되면 0.375 GB-초(0.125GB × 3초)가 소모됩니다.
40만 GB-초는 상당히 여유로운 한도이므로 소규모 프로젝트에서는 거의 무료로 사용할 수 있습니다. 위의 코드는 Cost Explorer API로 프리티어 사용량을 조회하는 방법을 보여줍니다.
get_cost_and_usage() 함수에서 Metrics를 'UsageQuantity'로 설정하면 비용이 아닌 사용량을 조회할 수 있습니다. 예를 들어 EC2의 경우 "시간(hours)", S3의 경우 "바이트(bytes)" 단위로 반환됩니다.
이 값을 프리티어 한도와 비교하면 얼마나 사용했는지 퍼센트로 계산할 수 있습니다. 또한 AWS 콘솔의 Billing Dashboard에서 "프리티어" 탭을 확인하면 시각적으로 사용량을 볼 수 있습니다.
서비스별로 진행 바(progress bar)가 표시되어 한도의 몇 퍼센트를 사용했는지 한눈에 알 수 있습니다. 실제 현업에서는 어떻게 관리할까요?
많은 개발자들이 월 초에 프리티어 사용량을 리셋한다고 착각합니다. 하지만 프리티어는 가입일 기준으로 계산됩니다.
예를 들어 2025년 3월 15일에 가입했다면, 프리티어 기간은 2026년 3월 14일까지입니다. 월별 한도는 매월 15일에 리셋됩니다.
이 사실을 모르고 월 초에 리소스를 추가했다가 예상치 못한 요금을 받는 경우가 많습니다. 또한 리전별 사용량은 합산됩니다.
서울 리전에서 EC2 인스턴스를 400시간, 버지니아 리전에서 400시간 사용하면 총 800시간이므로 50시간이 초과됩니다. 프리티어는 글로벌 계정 단위로 계산되므로 여러 리전을 사용할 때 주의해야 합니다.
하지만 주의할 점도 있습니다. 초보 개발자들이 흔히 하는 실수 중 하나는 데이터 전송 비용을 간과하는 것입니다.
EC2 인스턴스 자체는 프리티어 한도 내에 있지만, 인터넷으로 데이터를 전송하면 별도 요금이 부과됩니다. 아웃바운드 데이터 전송은 월 100GB까지 무료이지만, 대용량 파일을 다운로드하는 서비스라면 쉽게 초과할 수 있습니다.
또한 EBS 스냅샷도 주의해야 합니다. EBS 볼륨은 30GB까지 무료이지만, 스냅샷은 별도로 저장 공간을 차지합니다.
매일 스냅샷을 생성하면 30GB를 쉽게 넘을 수 있습니다. 다시 최입문 씨의 이야기로 돌아가 봅시다.
한고수 씨의 조언을 들은 최입문 씨는 불필요한 EC2 인스턴스를 종료하고 하나만 남겨뒀습니다. 그리고 매주 프리티어 대시보드를 확인하는 습관을 들였습니다.
"이제는 한도를 넘지 않아요!" 프리티어를 제대로 활용하면 비용 없이 AWS를 충분히 배울 수 있습니다. 여러분도 프리티어 한도를 숙지하고 정기적으로 사용량을 체크하는 습관을 들여보세요.
실전 팁
💡 - 프리티어 기간은 가입일 기준이므로 정확한 종료일을 캘린더에 표시해두세요
- EC2 인스턴스는 t2.micro 또는 t3.micro만 프리티어에 해당하며, 한 번에 하나만 실행하는 것이 안전합니다
- Billing Dashboard의 "프리티어" 탭을 주간 단위로 확인하여 한도 초과를 조기에 발견하세요
6. 예상치 못한 과금 방지 팁
윤개발 씨는 AWS를 1년 동안 사용하면서 여러 번 예상치 못한 청구서를 받았습니다. "분명 다 껐는데 요금이 나와요." 이제는 경험을 통해 숨어있는 과금 요소들을 모두 파악하게 되었습니다.
예상치 못한 과금 방지는 AWS의 숨겨진 비용 요소를 미리 파악하고 차단하는 것입니다. 마치 숨은 구독료를 찾아내는 것처럼, 눈에 잘 띄지 않는 리소스와 설정을 꼼꼼히 점검하여 불필요한 비용을 제거해야 합니다.
작은 실수들이 쌓이면 큰 금액이 될 수 있습니다.
다음 코드를 살펴봅시다.
import boto3
def find_hidden_costs(region='ap-northeast-2'):
"""숨어있는 과금 요소 찾기"""
ec2 = boto3.client('ec2', region_name=region)
s3 = boto3.client('s3')
print("=== 숨은 비용 요소 검사 ===\n")
# 1. 분리된 EBS 볼륨 (인스턴스 없이 남아있음)
volumes = ec2.describe_volumes(
Filters=[{'Name': 'status', 'Values': ['available']}]
)
if volumes['Volumes']:
print(f"⚠️ 분리된 EBS 볼륨: {len(volumes['Volumes'])}개")
for vol in volumes['Volumes']:
print(f" - {vol['VolumeId']}: {vol['Size']}GB")
# 2. 할당된 Elastic IP (연결되지 않음)
addresses = ec2.describe_addresses(
Filters=[{'Name': 'instance-id', 'Values': []}]
)
if addresses['Addresses']:
print(f"\n⚠️ 미연결 Elastic IP: {len(addresses['Addresses'])}개")
for addr in addresses['Addresses']:
print(f" - {addr['PublicIp']}")
# 3. NAT Gateway (시간당 과금)
nat_gateways = ec2.describe_nat_gateways(
Filters=[{'Name': 'state', 'Values': ['available']}]
)
if nat_gateways['NatGateways']:
print(f"\n⚠️ 실행 중인 NAT Gateway: {len(nat_gateways['NatGateways'])}개")
# 4. 오래된 스냅샷
snapshots = ec2.describe_snapshots(OwnerIds=['self'])
old_snapshots = [s for s in snapshots['Snapshots']
if (datetime.now() - s['StartTime'].replace(tzinfo=None)).days > 90]
if old_snapshots:
print(f"\n⚠️ 90일 이상 된 스냅샷: {len(old_snapshots)}개")
print("\n✅ 검사 완료")
윤개발 씨는 2년 차 풀스택 개발자입니다. AWS를 처음 배우면서 여러 번 뼈아픈 경험을 했습니다.
첫 달에는 Elastic IP 때문에 15달러, 두 번째 달에는 NAT Gateway 때문에 40달러, 세 번째 달에는 EBS 스냅샷 때문에 30달러를 냈습니다. 매번 청구서를 받을 때마다 "이번에는 또 뭐지?"라고 고민하는 것이 지겹던 윤개발 씨는 AWS 비용 최적화 전문가인 전문가 씨를 찾아갔습니다.
"AWS에는 숨어있는 과금 요소가 많아요. 체크리스트를 만들어서 정기적으로 확인하는 게 좋아요." 가장 흔한 숨은 비용 첫 번째는 EBS 볼륨입니다.
EC2 인스턴스를 종료하면 컴퓨팅 요금은 멈춥니다. 하지만 연결된 EBS 볼륨은 "Delete on Termination" 설정이 비활성화되어 있으면 그대로 남습니다.
볼륨은 "사용 가능(available)" 상태로 바뀌지만 삭제되지 않으므로 매달 GB당 0.1달러씩 요금이 나옵니다. 30GB 볼륨 하나면 월 3달러, 10개면 30달러입니다.
쉽게 비유하자면, EBS 볼륨은 마치 외장 하드디스크 대여 서비스와 같습니다. 컴퓨터(EC2)는 반납했지만 외장 하드(EBS)는 그대로 빌리고 있는 상황입니다.
사용하지 않아도 보관료는 계속 나옵니다. 두 번째 숨은 비용은 Elastic IP입니다.
Elastic IP는 인스턴스에 연결되어 있을 때는 무료입니다. 하지만 할당만 하고 연결하지 않으면 시간당 0.005달러가 부과됩니다.
한 달이면 약 3.6달러입니다. 많은 개발자들이 "고정 IP가 필요할 것 같아서" 미리 할당해두고 잊어버립니다.
개발하다가 인스턴스를 중지하면 Elastic IP는 자동으로 연결 해제되며, 이때부터 요금이 발생합니다. 세 번째 숨은 비용은 NAT Gateway입니다.
NAT Gateway는 프라이빗 서브넷의 EC2 인스턴스가 인터넷에 접속할 수 있도록 해주는 서비스입니다. 하지만 시간당 0.045달러, 한 달이면 약 32달러가 부과됩니다.
개발 환경에서 굳이 필요하지 않다면 삭제하는 것이 좋습니다. 대신 EC2 인스턴스에 퍼블릭 IP를 부여하거나, 필요할 때만 NAT Instance를 사용하는 방법도 있습니다.
네 번째 숨은 비용은 스냅샷입니다. EBS 스냅샷은 백업용으로 유용하지만, 삭제하지 않으면 영구히 저장됩니다.
매주 스냅샷을 생성하면 한 달에 4개, 1년이면 48개가 쌓입니다. 각 스냅샷이 10GB라면 480GB로, 월 48달러가 나옵니다.
AMI(Amazon Machine Image)를 삭제하더라도 연결된 스냅샷은 별도로 삭제해야 한다는 점도 주의해야 합니다. 다섯 번째 숨은 비용은 Load Balancer입니다.
Application Load Balancer는 시간당 0.025달러, 한 달이면 약 18달러입니다. 테스트용으로 만든 로드 밸런서를 삭제하지 않고 방치하면 매달 비용이 누적됩니다.
더 큰 문제는 Classic Load Balancer입니다. 오래된 프로젝트에 남아있는 경우가 많은데, AWS는 더 이상 권장하지 않지만 삭제하지 않으면 계속 과금됩니다.
여섯 번째 숨은 비용은 S3 버전 관리입니다. S3 버킷에서 버전 관리를 활성화하면 파일을 덮어쓰거나 삭제해도 이전 버전이 남아있습니다.
같은 파일을 100번 업데이트하면 100개 버전이 저장되어 용량이 100배로 늘어납니다. 버전 관리가 필요 없다면 비활성화하고, 필요하다면 수명 주기 정책으로 오래된 버전을 자동 삭제하도록 설정하세요.
일곱 번째 숨은 비용은 CloudWatch Logs입니다. Lambda, ECS, RDS 등의 로그가 CloudWatch Logs에 계속 쌓이면 저장 용량만큼 요금이 부과됩니다.
GB당 0.03달러는 저렴해 보이지만, 로그가 수백 GB 쌓이면 무시할 수 없는 금액이 됩니다. 수명 주기 정책으로 7일 또는 30일 후 자동 삭제하도록 설정하는 것이 좋습니다.
위의 코드는 숨어있는 과금 요소를 자동으로 찾아주는 스크립트입니다. 먼저 describe_volumes()로 상태가 "available"인 EBS 볼륨을 조회합니다.
이는 인스턴스에 연결되지 않은 볼륨으로, 삭제하지 않으면 계속 과금됩니다. 다음으로 describe_addresses()로 인스턴스에 연결되지 않은 Elastic IP를 찾습니다.
describe_nat_gateways()로 실행 중인 NAT Gateway를 확인하고, describe_snapshots()로 90일 이상 된 오래된 스냅샷을 찾아냅니다. 이 스크립트를 Lambda로 실행하고 결과를 슬랙으로 전송하면 팀 전체가 숨은 비용을 빠르게 파악할 수 있습니다.
실제 현업에서는 어떻게 관리할까요? 많은 기업에서는 AWS Trusted Advisor를 활용합니다.
Trusted Advisor는 비용 최적화, 보안, 성능 등을 자동으로 분석하여 개선 사항을 제안합니다. 비즈니스 이상 지원 플랜에서는 모든 검사를 사용할 수 있지만, 무료 플랜에서도 몇 가지 기본 검사는 가능합니다.
또한 태그 기반 자동 정리를 구현합니다. "CreatedBy", "ExpiresAt" 같은 태그를 붙여서 특정 날짜가 지나면 Lambda가 자동으로 리소스를 삭제하는 방식입니다.
개발자가 테스트용 리소스를 만들 때 "ExpiresAt: 2025-12-31"을 태그로 달아두면 해당 날짜에 자동으로 제거됩니다. 하지만 주의할 점도 있습니다.
초보 개발자들이 흔히 하는 실수 중 하나는 리전을 여러 곳에 분산하는 것입니다. 서울, 도쿄, 버지니아 리전에 각각 리소스가 흩어져 있으면 관리가 어렵고 숨은 비용을 놓치기 쉽습니다.
가능하면 한 리전에 집중하고, 필요한 경우에만 다른 리전을 사용하는 것이 좋습니다. 또한 자동화 스크립트도 비용이 듭니다.
Lambda는 상시 무료이지만 API 호출 횟수가 많으면 요금이 발생할 수 있습니다. 불필요하게 복잡한 자동화보다는 간단하고 효율적인 스크립트를 작성하세요.
다시 윤개발 씨의 이야기로 돌아가 봅시다. 전문가 씨의 조언을 들은 윤개발 씨는 체크리스트를 만들었습니다.
매주 금요일 오후에 EBS 볼륨, Elastic IP, NAT Gateway, 스냅샷을 점검하는 루틴을 만들었고, 불필요한 리소스를 정리했습니다. "이제는 예상치 못한 청구서가 안 와요!" 예상치 못한 과금은 대부분 숨어있는 리소스 때문입니다.
여러분도 정기적인 점검 루틴을 만들어서 AWS 비용을 통제하는 습관을 들여보세요.
실전 팁
💡 - 매주 또는 격주로 "숨은 비용 점검 루틴"을 만들어 EBS, Elastic IP, NAT Gateway, 스냅샷을 확인하세요
- AWS Trusted Advisor의 무료 검사를 활용하여 비용 최적화 제안을 받으세요
- 태그에 "ExpiresAt" 날짜를 추가하여 자동으로 오래된 리소스를 정리하는 Lambda 함수를 구축하세요
이상으로 학습을 마칩니다. 위 내용을 직접 코드로 작성해보면서 익혀보세요!
댓글 (0)
함께 보면 좋은 카드 뉴스
VPC 네트워크의 기초 - CIDR과 서브넷 설계 완벽 가이드
초급 개발자를 위한 VPC와 서브넷 설계 입문서입니다. 도서관 비유로 CIDR 개념을 쉽게 이해하고, 실무에서 자주 사용하는 서브넷 분할 전략을 단계별로 배워봅니다. 점프 투 자바 스타일로 술술 읽히는 네트워크 입문 가이드입니다.
AWS Certificate Manager로 HTTPS 인증서 발급 완벽 가이드
AWS Certificate Manager를 사용하여 무료로 SSL/TLS 인증서를 발급받고, 로드 밸런서에 적용하여 안전한 HTTPS 웹 서비스를 구축하는 방법을 초급자도 쉽게 따라 할 수 있도록 단계별로 안내합니다.
Route 53으로 도메인 연결 완벽 가이드
AWS Route 53을 사용하여 도메인을 등록하고 실제 서비스에 연결하는 전 과정을 실무 스토리와 함께 쉽게 배워봅니다. DNS의 기본 개념부터 레코드 설정, ELB 연결까지 초급 개발자도 쉽게 따라할 수 있도록 구성했습니다.
AWS RDS 관리형 데이터베이스 완벽 가이드
직접 데이터베이스를 설치하고 관리하는 것이 부담스러운 초급 개발자를 위한 RDS 가이드입니다. 데이터베이스 엔진 선택부터 인스턴스 생성, 보안 설정, 백업까지 실무에 필요한 모든 내용을 다룹니다.
AWS Auto Scaling 완벽 가이드
트래픽 급증에 대비하는 자동 확장 시스템을 단계별로 구축합니다. AMI 생성부터 Auto Scaling Group 설정, 테스트까지 초급 개발자를 위해 실무 중심으로 설명합니다.