AWS/GCP 요금 폭탄 방어: 예산 초과 알림(Billing Alarm) 및 람다(Lambda) 자동 차단 아키텍처

AWS/GCP 요금 폭탄 방어: 예산 초과 알림(Billing Alarm) 및 람다(Lambda) 자동 차단 아키텍처

"주말에 잠깐 테스트용으로 열어둔 EC2 인스턴스를 끄는 것을 깜빡했는데, 월요일에 300만 원짜리 청구서가 날아왔습니다."

클라우드 환경(AWS, GCP 등)을 도입하는 수많은 B2B 스타트업과 개발자들이 겪는 통과의례이자 가장 끔찍한 악몽입니다. 클라우드는 쓴 만큼 과금되는 혁신적인 시스템이지만, 반대로 말하면 해커의 디도스(DDoS) 공격이나 무한 루프 에러가 발생했을 때 당신의 신용카드 한도 끝까지 자원을 무한대로 뽑아다 쓴다는 뜻입니다.

대부분의 실무자는 AWS Budgets나 GCP Billing에서 '예산의 80% 도달 시 이메일 알림' 정도만 설정해 둡니다. 하지만 새벽 3시나 주말에 이메일이 온다면 누가 서버를 끌 것인가요? 본 가이드에서는 인간의 개입 없이, 예산 임계치 도달 시 스스로 시스템의 숨통을 끊어 자본을 보호하는 '자동 차단(Kill-Switch)' 아키텍처를 단호하게 제시합니다.

1단계: 핵심 원인 분석 (알림과 행동의 분리)

에러의 근본적인 원인은 '모니터링(Monitoring)'과 '액션(Action)'이 분리되어 있다는 것입니다. 알림을 받았음에도 사람이 콘솔에 접속해 버튼을 누르기 전까지 과금 미터기는 초당 수만 원씩 돌아갑니다. 이 틈을 메우기 위해서는 알림 이벤트(SNS/PubSub)가 발생했을 때 즉각적으로 서버 코드를 실행할 수 있는 서버리스 함수(AWS Lambda 등)를 직접 연결(Trigger)해야만 합니다.

2단계: 예산 경보와 SNS(Simple Notification Service) 연동

먼저 AWS Budgets에서 예산을 100달러로 설정합니다. 그리고 임계값(Threshold)을 90%로 잡은 뒤, 알림 수신처를 일반 이메일이 아닌 'Amazon SNS 주제(Topic)'로 지정합니다. 이렇게 하면 예산 초과 시 시스템이 기계가 읽을 수 있는 데이터 페이로드(JSON)를 SNS라는 확성기를 통해 파이프라인으로 방송하게 됩니다.

3단계: 완벽한 해결책 - Lambda 킬 스위치(Kill-Switch) 코드 구축

SNS 주제를 구독(Subscribe)하는 AWS Lambda 함수를 생성합니다. 이 파이썬(Python) 함수는 경보를 수신하는 즉시 AWS 계정 내에 돌아가고 있는 돈 먹는 하마(EC2 인스턴스, RDS 등)를 강제로 Stop 시킵니다.


import boto3
import os

# EC2 및 RDS 클라이언트 초기화
ec2_client = boto3.client('ec2')
rds_client = boto3.client('rds')

def lambda_handler(event, context):
    print("🚨 [CRITICAL] 예산 초과 경보 수신. 킬 스위치를 가동합니다.")
    
    try:
        # 1. 실행 중인 모든 EC2 인스턴스 검색 및 강제 중지
        instances = ec2_client.describe_instances(Filters=[{'Name': 'instance-state-name', 'Values': ['running']}])
        instance_ids = [i['InstanceId'] for r in instances['Reservations'] for i in r['Instances']]
        
        if instance_ids:
            ec2_client.stop_instances(InstanceIds=instance_ids)
            print(f"EC2 인스턴스 중지 완료: {instance_ids}")
        
        # 2. 프로비저닝된 데이터베이스(RDS) 강제 중지 (Aurora 제외)
        dbs = rds_client.describe_db_instances()
        for db in dbs['DBInstances']:
            if db['DBInstanceStatus'] == 'available':
                rds_client.stop_db_instance(DBInstanceIdentifier=db['DBInstanceIdentifier'])
                print(f"RDS 인스턴스 중지 완료: {db['DBInstanceIdentifier']}")
                
        return {"statusCode": 200, "body": "모든 주요 리소스 강제 종료 완료. 자본 방어 성공."}
        
    except Exception as e:
        print(f"킬 스위치 가동 중 치명적 에러 발생: {e}")
        raise e

이 코드는 타는 불에 소화기를 던져 넣는 것과 같습니다. 람다 함수에는 반드시 EC2와 RDS를 중지(Stop)할 수 있는 IAM 권한(Role)이 부여되어야 작동합니다.

💡 아키텍트의 시선 (Insight)

클라우드 환경에서 아키텍트의 진정한 실력은 시스템을 켜는 것이 아니라, '어떻게 우아하고 안전하게 시스템을 끌 것인가'에서 판가름 납니다. 킬 스위치가 없는 인프라는 브레이크 없는 스포츠카와 같습니다. 예산 자동 차단 아키텍처를 도입하는 순간, 당신은 금요일 퇴근 후 두 다리를 뻗고 완벽한 주말을 즐길 수 있는 자유를 얻게 될 것입니다.

댓글

이 블로그의 인기 게시물

Zapier & Make.com 자동화의 덫: 무한 루프(Infinite Loop) 에러 완벽 방어 아키텍처

엑셀 보고서의 종말: 구글 스프레드시트와 루커 스튜디오(Looker Studio)로 실시간 대시보드 구축하기

Docker OOMKilled (Exit Code 137) 에러의 진실: 컨테이너 메모 누수 방어 및 리소스 최적화 아키텍처