← 목록으로AWS

SNS SMS 크로스 리전 구성 — Seoul에서 Tokyo 경유 문자 알림 발송

Seoul 리전의 SMS 미지원 제약을 Tokyo 리전 경유로 해결. CloudWatch Alarm → SNS → Lambda → Tokyo SNS → SMS 파이프라인 구축과 Sandbox 환경 운영 노하우

AWSSNSSMSMonitoringLambda
2024-08-10

배경

CloudWatch 알람 발생 시 운영 담당자에게 문자(SMS)를 보내야 하는데, Seoul 리전(ap-northeast-2)은 SNS SMS 발송을 지원하지 않습니다. 이 제약을 해결하기 위해 Tokyo 리전(ap-northeast-1)을 경유하는 크로스 리전 SMS 발송 구조를 설계했습니다.


아키텍처

CloudWatch Alarm (Seoul)
  → SNS Topic: cloudwatch-alarm-topic (Seoul)
    → Lambda: sns-forward-to-tokyo (Seoul)
      → SNS Topic: cloudwatch-alarm-topic-tokyo (Tokyo)
        → SMS 발송 (6명 구독)

Seoul에서 발생한 알람 메시지를 Lambda가 받아서 Tokyo 리전의 SNS Topic으로 전달하고, Tokyo SNS가 등록된 전화번호로 SMS를 발송하는 구조입니다.


Lambda: sns-forward-to-tokyo

Seoul SNS Topic의 구독자로 등록된 Lambda 함수가 메시지를 받아 Tokyo SNS로 포워딩합니다.

import boto3
import json
 
# Tokyo 리전의 SNS 클라이언트
sns_tokyo = boto3.client('sns', region_name='ap-northeast-1')
 
TOKYO_TOPIC_ARN = 'arn:aws:sns:ap-northeast-1:[account-id]:cloudwatch-alarm-topic-tokyo'
 
def lambda_handler(event, context):
    # Seoul SNS에서 전달된 메시지 파싱
    sns_message = event['Records'][0]['Sns']
    subject = sns_message.get('Subject', 'CloudWatch Alarm')
    message = sns_message['Message']
 
    # 메시지를 SMS에 적합한 형태로 가공
    # SNS SMS는 160자 제한이 있으므로 핵심 정보만 추출
    alarm_info = json.loads(message)
    alarm_name = alarm_info.get('AlarmName', 'Unknown')
    new_state = alarm_info.get('NewStateValue', 'Unknown')
    reason = alarm_info.get('NewStateReason', '')[:80]
 
    sms_message = f"[알람] {alarm_name}\n상태: {new_state}\n{reason}"
 
    # Tokyo SNS Topic으로 발행
    sns_tokyo.publish(
        TopicArn=TOKYO_TOPIC_ARN,
        Subject=subject,
        Message=sms_message
    )
 
    return {'statusCode': 200}

IAM 권한

Lambda 실행 역할에 Tokyo 리전 SNS 발행 권한이 필요합니다.

{
  "Effect": "Allow",
  "Action": "sns:Publish",
  "Resource": "arn:aws:sns:ap-northeast-1:[account-id]:cloudwatch-alarm-topic-tokyo"
}

Tokyo SNS SMS 설정

Sandbox 환경

Tokyo 리전의 SNS SMS는 Sandbox 상태로 운영 중입니다. Sandbox에서는 사전 등록(Verified)된 전화번호에만 SMS를 발송할 수 있습니다.

항목상태
월간 지출 한도$50
전송 성공 샘플링100%
샌드박스 상태Sandbox (등록된 번호만 발송 가능)

전화번호 등록

SMS를 수신할 담당자 번호를 Sandbox에 등록합니다.

SNS 콘솔 (Tokyo) → Mobile → Text messaging (SMS)
→ Sandbox destination phone numbers → Add phone number
→ 인증 코드 수신 → Verified 완료

운영팀 담당자 번호를 등록하여 CloudWatch 알람 SMS를 수신합니다.

Sandbox 해제(프로덕션 전환)를 위해서는 AWS Support에 사용 사례를 설명하고 승인을 받아야 합니다. 현재는 수신 대상이 내부 담당자로 한정되어 있어 Sandbox로 충분합니다.


SNS Topic 구독 구성

Seoul SNS Topic

Topic구독 프로토콜대상용도
cloudwatch-alarm-topicLambdasns-forward-to-tokyoSMS 포워딩 허브

이 Topic에는 SMS 외에도 이메일 구독이 연결되어 있어, 하나의 알람이 이메일 + SMS 동시 발송됩니다.

Tokyo SNS Topic

Topic구독 프로토콜구독자 수용도
cloudwatch-alarm-topic-tokyoSMS6명CloudWatch 알람 SMS
서비스별 타임아웃 알림 TopicSMS1~6명서비스 타임아웃 SMS
운영 알림 TopicSMS1명운영 SMS

SMS 알림 대상 CloudWatch 알람

Seoul의 cloudwatch-alarm-topic에 연결된 알람들이 Tokyo를 경유하여 SMS로 전달됩니다.

서비스알람 항목
애플리케이션 서버 (Worker Node, 코디네이터)CPU, 메모리, 디스크
DB 서버 (Primary)CPU, 메모리, 디스크(OS/데이터 볼륨), SWAP
애플리케이션 서버 (PRD)CPU, 메모리, 디스크(OS/SW 볼륨), SWAP
DB 서버 (Replica)CPU, 메모리, 디스크(OS/데이터 볼륨)
FTP 서버 (Windows)CPU, 메모리, 다중 드라이브
연동 서버 (IS)CPU, 메모리, 디스크(OS/데이터)
배치 서비스메모리

트러블슈팅

SMS 미수신 문제

SMS가 발송되었으나 수신되지 않는 경우, Tokyo SNS의 전송 상태 로그를 확인합니다.

SNS 콘솔 (Tokyo) → Text messaging (SMS) → Message delivery status
→ CloudWatch Logs에서 전송 성공/실패 로그 확인

주요 실패 원인:

  • 전화번호 형식 오류 (국가 코드 포함 필요: +82...)
  • Sandbox에 미등록된 번호
  • 월간 지출 한도 초과

메시지 길이 제한

SNS SMS는 단일 메시지 160자(영문) 또는 70자(한글) 제한이 있습니다. CloudWatch 알람 메시지는 원본이 길기 때문에, Lambda에서 핵심 정보만 추출하여 SMS에 적합한 길이로 가공합니다.


비용

항목비용
SNS SMS 발송 (한국)$0.047 / 건
Lambda 실행무료 (프리티어)
SNS Topic 발행무료 (월 100만 건까지)
월간 지출 한도$50 (설정 변경 가능)

월 100건 SMS 발송 기준 약 $4.7 수준입니다.


정리

  • Seoul 리전 SMS 미지원 제약을 Lambda + Tokyo SNS 크로스 리전 구조로 해결
  • CloudWatch Alarm → Seoul SNS → Lambda → Tokyo SNS → SMS 파이프라인 구축
  • Sandbox 환경에서 운영팀 담당자 번호를 Verified 등록하여 운영
  • Lambda에서 메시지를 SMS 적합 길이로 가공하여 핵심 정보만 전달
  • 월 ~$5 수준의 저비용 SMS 알림 운영