SNS 이메일 알림이 안 올 때 — 구독 확인 링크부터 점검하라
SNS 토픽을 만들고 이메일 구독까지 등록했는데 알림이 하나도 안 온다. 가장 먼저 의심해야 할 건 코드도 IAM도 아니다 — 구독 확인(Subscription Confirmation) 이메일을 클릭했는지 여부다. 이 단계를 건너뛰면 SNS는 메시지를 발행해도 해당 엔드포인트로 전달하지 않는다.
TL;DR — SNS 이메일 알림 미수신 핵심 체크리스트
| 점검 항목 | 확인 방법 | 조치 |
|---|---|---|
| 구독 상태가 'PendingConfirmation' | AWS 콘솔 또는 CLI로 구독 목록 조회 | 확인 이메일의 링크 클릭 또는 재발송 |
| 확인 이메일이 스팸함에 있음 | 수신 이메일함 스팸 폴더 확인 | 스팸 해제 후 링크 클릭 |
| 토픽에 메시지가 실제로 발행되지 않음 | CloudWatch 지표 NumberOfMessagesSent 확인 | Publish API 또는 콘솔에서 테스트 메시지 발행 |
| 구독 필터 정책이 메시지를 차단 | 구독 속성의 FilterPolicy 확인 | 필터 정책 제거 또는 메시지 속성 추가 |
| 잘못된 이메일 주소로 구독 등록 | 구독 엔드포인트 값 확인 | 구독 삭제 후 올바른 주소로 재등록 |
SNS 이메일 구독의 동작 원리
SNS 이메일 알림이 왜 안 오는지 이해하려면 구독 생성부터 메시지 전달까지의 흐름을 알아야 한다. SNS는 이메일 엔드포인트를 등록할 때 즉시 활성화하지 않는다. 반드시 수신자가 확인 이메일의 링크를 클릭해야 구독이 'Confirmed' 상태로 전환된다. 이 설계는 동의 없이 타인의 이메일로 메시지를 보내는 것을 방지하기 위한 것이다.
(protocol: email) SNS-->>Email: 확인 이메일 발송
(Subscription Confirmation) Note over SNS: 구독 상태: PendingConfirmation Email-->>User: 확인 링크 클릭 User->>SNS: 확인 링크 GET 요청 SNS-->>SNS: 구독 상태 변경
PendingConfirmation → Confirmed Note over SNS: 이제부터 메시지 전달 활성화 SNS-->>Email: 토픽 메시지 전달
- 구독 생성 요청:
subscribeAPI 호출 시 SNS는 구독을 'PendingConfirmation' 상태로 등록한다. - 확인 이메일 발송: SNS가 등록된 이메일 주소로 확인 링크가 담긴 이메일을 자동 발송한다.
- 수신자 확인: 수신자가 이메일의 'Confirm subscription' 링크를 클릭해야 상태가 'Confirmed'로 바뀐다.
- 메시지 전달 활성화: 상태가 'Confirmed'인 구독에만 토픽 메시지가 전달된다. 'PendingConfirmation' 상태에서는 메시지가 전달되지 않는다.
구독 확인 링크는 발송 후 3일간 유효하다. 기간이 지나면 링크가 만료되고, 구독은 자동으로 삭제된다. 다시 구독을 등록해야 한다.
SNS 이메일 알림 미수신 — 단계별 진단
1단계: 구독 상태 확인
가장 먼저 해야 할 일은 구독이 실제로 'Confirmed' 상태인지 확인하는 것이다. 콘솔에서 확인할 수도 있지만, CLI로 조회하면 모든 구독의 상태를 한눈에 볼 수 있다. 'PendingConfirmation'이 보이면 이메일을 확인하지 않은 것이다.
# 특정 토픽의 모든 구독 목록과 상태 조회
aws sns list-subscriptions-by-topic \
--topic-arn arn:aws:sns:us-east-1:123456789012:MyAlertTopic
출력 결과에서 SubscriptionArn 값이 PendingConfirmation으로 표시되면 아직 확인이 완료되지 않은 상태다. 'Confirmed' 상태라면 구독 ARN이 정상적으로 출력된다.
2단계: 확인 이메일 재발송
확인 이메일을 못 찾겠거나 링크가 만료됐다면, 구독을 삭제하고 다시 등록하는 것이 가장 빠르다. SNS 콘솔에서 직접 재발송하는 버튼은 없다. 구독을 재생성하면 확인 이메일이 다시 발송된다.
# 기존 PendingConfirmation 구독 삭제
# (SubscriptionArn이 'PendingConfirmation'인 경우 ARN이 없으므로 콘솔에서 삭제)
# 구독 재등록 — 확인 이메일이 다시 발송됨
aws sns subscribe \
--topic-arn arn:aws:sns:us-east-1:123456789012:MyAlertTopic \
--protocol email \
--notification-endpoint your-email@example.com
명령 실행 후 수신 이메일함(스팸 포함)에서 'AWS Notification - Subscription Confirmation' 제목의 이메일을 찾아 링크를 클릭한다.
3단계: 토픽에 테스트 메시지 발행
구독이 'Confirmed' 상태인데도 이메일이 안 온다면, 토픽에 메시지가 실제로 발행되고 있는지 확인해야 한다. 알람 조건이 충족되지 않아서 메시지 자체가 발행되지 않는 경우도 흔하다. CLI로 직접 테스트 메시지를 발행해서 전달 경로를 검증한다.
# 토픽에 테스트 메시지 직접 발행
aws sns publish \
--topic-arn arn:aws:sns:us-east-1:123456789012:MyAlertTopic \
--subject 'SNS 테스트 알림' \
--message 'SNS 이메일 전달 테스트 메시지입니다.'
이 명령 실행 후 이메일이 도착하면 SNS 자체는 정상이다. 문제는 알람 소스(CloudWatch Alarm, EventBridge 등)가 SNS를 트리거하지 않는 것이다.
4단계: CloudWatch 지표로 메시지 전달 현황 확인
SNS는 메시지 발행 및 전달 성공/실패에 대한 CloudWatch 지표를 제공한다. 테스트 메시지는 도착하는데 실제 알람 메시지가 안 온다면, 알람 소스 설정을 점검해야 한다는 신호다.
# SNS 토픽의 메시지 발행 수 확인 (최근 1시간)
aws cloudwatch get-metric-statistics \
--namespace AWS/SNS \
--metric-name NumberOfMessagesPublished \
--dimensions Name=TopicName,Value=MyAlertTopic \
--start-time $(date -u -d '1 hour ago' +%Y-%m-%dT%H:%M:%SZ) \
--end-time $(date -u +%Y-%m-%dT%H:%M:%SZ) \
--period 3600 \
--statistics Sum
5단계: 구독 필터 정책 확인
구독에 필터 정책(Filter Policy)이 설정되어 있으면, 메시지 속성이 필터 조건과 일치하지 않는 경우 해당 구독으로 메시지가 전달되지 않는다. 이 설정은 조용히 메시지를 차단하기 때문에 놓치기 쉽다.
# 구독 ARN으로 필터 정책 포함 구독 속성 조회
aws sns get-subscription-attributes \
--subscription-arn arn:aws:sns:us-east-1:123456789012:MyAlertTopic:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
출력에서 FilterPolicy 키가 있고 값이 비어 있지 않다면, 발행하는 메시지에 해당 속성이 포함되어야 한다. 테스트 목적으로 필터 정책을 제거하려면 아래 명령을 사용한다.
# 구독에서 필터 정책 제거
aws sns set-subscription-attributes \
--subscription-arn arn:aws:sns:us-east-1:123456789012:MyAlertTopic:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx \
--attribute-name FilterPolicy \
--attribute-value '{}'
실제 사례 — CloudWatch Alarm이 SNS를 트리거하지 않는 경우
증상은 이랬다. SNS 구독은 'Confirmed' 상태고, CLI로 직접 발행한 테스트 메시지는 이메일로 잘 도착한다. 그런데 EC2 CPU 사용률이 임계값을 넘어도 알림이 오지 않는다.
처음엔 SNS 토픽 정책 문제라고 생각했다. 토픽 정책을 열어봤지만 CloudWatch가 Publish 권한을 가지고 있었다. 그 다음엔 CloudWatch Alarm 상태를 확인했는데 — Alarm 상태가 'INSUFFICIENT_DATA'였다. CPU 지표 데이터 포인트가 부족해서 알람 자체가 ALARM 상태로 전환되지 않은 것이었다.
실제 원인은 EC2 인스턴스의 세부 모니터링(Detailed Monitoring)이 비활성화된 상태에서 알람 평가 기간을 1분으로 설정한 것이었다. 기본 모니터링은 5분 단위로 지표를 수집하므로, 1분 평가 기간에는 데이터가 없어 'INSUFFICIENT_DATA'가 유지됐다.
# CloudWatch Alarm 현재 상태 확인
aws cloudwatch describe-alarms \
--alarm-names MyEC2CpuAlarm \
--query 'MetricAlarms[*].{Name:AlarmName,State:StateValue,Reason:StateReason}'
알람 상태가 'INSUFFICIENT_DATA'라면 SNS 문제가 아니다. 알람 평가 기간을 지표 수집 주기에 맞게 조정하거나, EC2 세부 모니터링을 활성화해야 한다.
ALARM 상태 전환] -->|sns:Publish| B[SNS Topic] B --> C{구독 상태 확인} C -->|Confirmed| D[이메일 전달] C -->|PendingConfirmation| E[전달 안 됨] A2[CloudWatch Alarm
INSUFFICIENT_DATA] -->|트리거 없음| F[SNS 미호출] F --> G[이메일 미수신] style E fill:#f66,color:#fff style G fill:#f66,color:#fff style D fill:#6a6,color:#fff
SNS 토픽 정책 — CloudWatch Alarm 연동 시 필수 권한
CloudWatch Alarm이 SNS 토픽에 메시지를 발행하려면 토픽 정책에 CloudWatch 서비스 주체(Principal)에 대한 sns:Publish 권한이 있어야 한다. AWS 콘솔에서 CloudWatch Alarm을 생성할 때 SNS 토픽을 지정하면 이 정책이 자동으로 추가되지만, CLI나 IaC로 직접 구성할 때는 누락되기 쉽다.
🔽 SNS 토픽 정책 예시 (CloudWatch Alarm 연동) — 클릭하여 펼치기
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowCloudWatchAlarmPublish",
"Effect": "Allow",
"Principal": {
"Service": "cloudwatch.amazonaws.com"
},
"Action": "sns:Publish",
"Resource": "arn:aws:sns:us-east-1:123456789012:MyAlertTopic",
"Condition": {
"ArnLike": {
"aws:SourceArn": "arn:aws:cloudwatch:us-east-1:123456789012:alarm:*"
}
}
}
]
}
# 현재 토픽 정책 확인
aws sns get-topic-attributes \
--topic-arn arn:aws:sns:us-east-1:123456789012:MyAlertTopic \
--query 'Attributes.Policy'
SNS 이메일 알림 설정 — 전체 진단 흐름
또는 구독 재등록] Q1 -->|Confirmed| Q2{테스트 메시지
직접 발행} Q2 -->|이메일 미수신| A2[토픽 정책 확인
필터 정책 확인] Q2 -->|이메일 수신| Q3{CloudWatch Alarm
상태 확인} Q3 -->|INSUFFICIENT_DATA| A3[평가 기간 조정
세부 모니터링 활성화] Q3 -->|OK 유지| A4[알람 임계값 및
조건 재검토] Q3 -->|ALARM 전환됨| A5[SNS 토픽 ARN
연결 설정 재확인] A1 --> End[알림 수신 확인] A2 --> End A3 --> End A4 --> End A5 --> End style Start fill:#e8a,color:#fff style End fill:#6a6,color:#fff
- 구독 상태가 'PendingConfirmation'이면 이메일 확인이 첫 번째 해결책이다.
- 구독이 'Confirmed'이면 테스트 메시지로 SNS 전달 경로를 검증한다.
- 테스트 메시지도 안 오면 토픽 정책과 필터 정책을 점검한다.
- 테스트 메시지는 오는데 알람 메시지가 안 오면 알람 소스(CloudWatch 등) 설정을 점검한다.
SNS 이메일 알림 — 마무리 및 다음 단계
SNS 이메일 알림 미수신의 대부분은 구독 확인 단계를 건너뛴 것에서 시작한다. 구독 상태를 CLI로 먼저 확인하는 습관을 들이면 불필요한 디버깅 시간을 줄일 수 있다. 구독이 정상 확인됐는데도 알림이 안 온다면, SNS 자체보다 알람 소스와 토픽 정책을 먼저 의심하라.
다음 단계로 고려할 수 있는 설정:
- SNS 메시지 전달 실패 로깅: 토픽 속성에서 전달 상태 로깅(Delivery Status Logging)을 활성화하면 CloudWatch Logs에서 전달 성공/실패 상세 내역을 확인할 수 있다.
- Dead-Letter Queue(DLQ) 설정: 이메일 전달 실패 시 메시지를 보존하려면 SQS DLQ를 구독에 연결할 수 있다. 단, 이메일 프로토콜 구독에 대한 DLQ 지원 여부는 공식 문서에서 확인하라.
- 관련 AWS 공식 문서: Amazon SNS 이메일 알림, SNS 구독 필터 정책
핵심 용어 정리
| 용어 | 설명 |
|---|---|
| PendingConfirmation | 구독 등록 후 수신자가 확인 링크를 클릭하기 전의 상태. 이 상태에서는 메시지가 전달되지 않는다. |
| Subscription Confirmation | SNS가 이메일 엔드포인트 등록 시 발송하는 확인 이메일. 링크 클릭으로 구독을 활성화한다. |
| Filter Policy | 구독 단위로 설정하는 메시지 필터링 규칙. 조건에 맞지 않는 메시지는 해당 구독으로 전달되지 않는다. |
| Topic Policy | SNS 토픽에 대한 리소스 기반 정책. 어떤 AWS 서비스나 계정이 토픽에 메시지를 발행할 수 있는지 제어한다. |
| INSUFFICIENT_DATA | CloudWatch Alarm 상태 중 하나. 알람을 평가하기 위한 지표 데이터가 충분하지 않을 때 표시된다. |
댓글
댓글 쓰기