
【VPC外リージョンサービス】
SNS(Amazon Simple Notification Service)は、Pub/Subモデル(Publish/Subscribe) に基づく通知サービスです。
Topic(トピック) に Message(メッセージ) を発行すると、Subscription(サブスクリプション) に登録された複数のエンドポイントへ自動的にファンアウト(配信)されます。対応する配信先には、HTTP/HTTPS、SQS(Simple Queue Service)、Lambda、Email 、SMS(Short Message Service)、 Application (mobile push) などがあります。
Message Filtering(メッセージフィルタリング) により、属性ベースで特定の条件に合致するメッセージのみを購読者に配信することができます。さらに、配信に失敗したメッセージを保持して後処理できる DLQ(Dead-Letter Queue) 機能も提供されています。
SNSはメッセージの暗号化(Encryption)や VPCエンドポイント を利用したセキュアな運用が可能であり、信頼性と可用性の高い通知基盤として多くのシステムで利用されています。
イベント駆動アーキテクチャの中心的な役割を担い、マイクロサービス間通信やアラート通知、リアルタイム連携など、幅広いユースケースで活用されています。
重要用語
ユースケース
| Pub/Subによるイベントファンアウト | 注文完了やユーザー登録などのイベントをSNSトピックに発行し、複数のシステム(Lambda、SQS、HTTPエンドポイント)がそれぞれ購読して別々の処理を行う。 |
| マイクロサービス間の疎結合通知 | あるサービス内で発生した出来事をSNSで通知し、他のサービスは通知を受け取ったときだけ処理を行うことで、直接の依存関係を減らす。 |
| メール・モバイル通知の中継基盤 | アプリケーションからの重要なお知らせやアラートをSNSトピックに送信し、メールやモバイルプッシュ通知へ配信する。 |
ベストプラクティス
| サブスクリプションフィルタポリシー | 不要なメッセージ配信を減らすために属性ベースのフィルタを設定する。 |
| 暗号化の有効化 | KMSと連携してトピックメッセージをサーバーサイドで暗号化する。 |
| 再試行ポリシーの調整 | エンドポイントの特性に合わせて再試行回数や間隔を設定する。 |
高可用性・バックアップ・リトライ
| 高可用性・バックアップ・リトライ設計のポイント |
|---|
| 【デフォルト】AWS内部で冗長化 ・メッセージ配信エンジン ・トピック定義・メタデータ ・サブスクリプション情報 ・メッセージの一時保存 ・配信ステータス管理 ・フィルタリングエンジン |
| 【自動リトライ】デフォルト 配信先ごとに自動リトライ機能がある HTTP / HTTPS(初回失敗後、最大 3 回、各 20 秒間隔:DeliveryPolicy で細かく指定可能) SQS / Lambda(合計 100,015 回、最長 23 日間リトライ:変更不可) SMS / モバイルプッシュ / Email(合計 50 回、6 時間以上かけてリトライ:変更不可) |
セキュリティ
| 関連サービス | 設定内容 |
|---|---|
| KMS(データの暗号化と鍵の安全管理) | 【トピックのメッセージの暗号化が必要】 独自KMSキーを使うことを推奨(鍵操作、監査) |
| Secrets Manager(機密情報の安全管理) | - |
| SSM Parameter Store(設定情報の一元管理) | - |
| CloudTrail(操作履歴の記録・監査・追跡) | 【自動記録】 作成・更新・削除・設定変更は自動記録される。(コントロールプレーンAPI) データ操作は追跡できない(データプレーンAPI) |
| Config(リソースの構成状態・設定変更を記録) | 【Configが有効な場合】 トピック設定変更履歴・暗号化/ポリシー公開の準拠評価 |
| GuardDuty(脅威を自動検出) | 【GuardDutyが有効な場合】 トピック削除やサブスクリプション変更のAPI異常検知 |
リソースベースポリシーによる補完
実行ロールで不足する権限をSNS のリソースベースポリシーで補うパターン
| リソースベースポリシーのPrincipal | リソースベースポリシーのAction |
|---|---|
| 【S3】 s3.amazonaws.com | sns:Publish |
| 【CloudWatch】 cloudwatch.amazonaws.com | sns:Publish |
| 【RDS】 rds.amazonaws.com | sns:Publish |
| 【ElastiCache】 elasticache.amazonaws.com | sns:Publish |
| 【Backup】 backup.amazonaws.com | sns:Publish |
ログ・監視
| ログ出力先 | ログの種類 |
|---|---|
| CloudWatch Logs | 配信ステータスログ |
標準メトリクス
| メトリクス名 | 説明 |
|---|---|
| NumberOfMessagesPublished | 発行されたメッセージ数 |
| NumberOfNotificationsFilteredOut | フィルタリングで破棄された通知数 |
| PublishSize | パブリッシュされたメッセージサイズ合計 |
| HTTPFailure | HTTPエンドポイントへの失敗通知数 |
| HTTPSuccess | HTTPエンドポイントへの成功通知数 |
| NumberOfNotificationsDelivered | 配信成功通知数 |
| NumberOfNotificationsFailed | 配信失敗通知数 |
| NumberOfNotificationsFilteredOutInvalidAttributes | 無効属性によるフィルタ数 |
| NumberOfNotificationsRedrivenToDLQ | DLQへ再投入された通知数 |
| SMSMonthToDateSpentUSD | SMS課金額(月累計) |
制限値(固定値/ハードリミット/ソフトリミット)
| ハードリミット | 制限値 |
|---|---|
| メッセージサイズ | 最大256 KB |
| SMSメッセージの長さ | 140 Bytes(GSM-7)、70文字(UCS-2) |
| フィルターポリシーのサイズ | 256 KB |
| メッセージ属性数 | 10 |
| ソフトリミット | 制限値 |
|---|---|
| トピック数/アカウント | 100,000 |
| サブスクリプション数/トピック | 12,500,000 |
| 公開スループット | 30,000メッセージ/秒 |
AWS CLIのサンプルコード
パターン1:インフラ監視 CloudWatch Alarms → SNS → email
SNS Topic を作成する
aws sns create-topic \
--name cloudwatch-alarm-notifications \
--attributes DisplayName="CloudWatch Alarm Notifications"
SNS Topic を表示する
aws sns list-topics
SNS Topic を削除する(SNS Topic のARN 指定)
aws sns delete-topic \
--topic-arn arn:aws:sns:ap-northeast-1:123456789012:cloudwatch-alarm-notifications
サブスクリプションを作成する(SNS Topic のARN、通知先エンドポイント 指定)
| protocol | endpoint |
|---|---|
| メールアドレス | |
| sms | +8190xxxx(E.164形式) |
| lambda | Lambda ARN |
| sqs | SQS ARN |
| https | HTTP エンドポイントの URL |
| application | Mobile push endpoint ARN |
| firehose | Firehose delivery stream ARN |
aws sns subscribe \
--topic-arn arn:aws:sns:ap-northeast-1:123456789012:cloudwatch-alarm-notifications \
--protocol email \
--notification-endpoint admin@example.com
サブスクリプションを表示する
aws sns list-subscriptions
サブスクリプションを削除する(サブスクリプションのARN 指定)
aws sns unsubscribe \
--subscription-arn arn:aws:sns:ap-northeast-1:123456789012:cloudwatch-alarm-notifications:abcd-1234-efgh-5678
CloudWatch Alarmとの連携を作成する(SNS Topic のARN 指定)
aws cloudwatch put-metric-alarm \
--alarm-name high-cpu-usage \
--alarm-description "Alert when CPU exceeds 80%" \
--metric-name CPUUtilization \
--namespace AWS/EC2 \
--statistic Average \
--period 300 \
--evaluation-periods 2 \
--threshold 80 \
--comparison-operator GreaterThanThreshold \
--dimensions Name=InstanceId,Value=i-1234567890abcdef0 \
--alarm-actions arn:aws:sns:ap-northeast-1:123456789012:cloudwatch-alarm-notifications
CloudWatch Alarmとの連携を表示する
aws cloudwatch describe-alarms
CloudWatch Alarmとの連携を削除する(アラーム名 指定)
aws cloudwatch delete-alarms \
--alarm-names high-cpu-usage
CloudWatchがSNSを呼び出すことを許可するリソースベースポリシーを作成する
(SNS Topic のARN、ポリシーファイル名 指定)
sns-policy.json
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "cloudwatch.amazonaws.com"
},
"Action": "SNS:Publish",
"Resource": "arn:aws:sns:ap-northeast-1:123456789012:cloudwatch-alarm-notifications"
}
]
}
aws sns set-topic-attributes \
--topic-arn arn:aws:sns:ap-northeast-1:123456789012:cloudwatch-alarm-notifications \
--attribute-name Policy \
--attribute-value file://sns-policy.json
リソースベースポリシーを表示する(SNS Topic のARN 指定)
aws sns get-topic-attributes \
--topic-arn arn:aws:sns:ap-northeast-1:123456789012:cloudwatch-alarm-notifications
リソースベースポリシーを削除する(SNS Topic のARN、ポリシー名 指定)
aws sns set-topic-attributes \
--topic-arn arn:aws:sns:ap-northeast-1:123456789012:cloudwatch-alarm-notifications \
--attribute-name Policy \
--attribute-value ""
パターン2:アプリケーション通知 Lambda → SNS → Lambda
SNS Topic を作成する
aws sns create-topic \
--name application-notifications \
--attributes DisplayName="Application Notifications"
サブスクリプションを作成する(SNS Topic のARN、通知先エンドポイント 指定)
aws sns subscribe \
--topic-arn arn:aws:sns:ap-northeast-1:123456789012:application-notifications \
--protocol lambda \
--notification-endpoint arn:aws:lambda:ap-northeast-1:123456789012:function:notification-handler
実行ロールを作成する(信頼ポリシーのファイル名 指定)
lambda-trust-policy.json
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "lambda.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
aws iam create-role \
--role-name LambdaSNSPublishRole \
--assume-role-policy-document file://lambda-trust-policy.json
カスタム管理ポリシーを作成する(ポリシーファイル名 指定)
sns-publish-policy.json
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"sns:Publish"
],
"Resource": "arn:aws:sns:ap-northeast-1:123456789012:application-notifications"
}
]
}
aws iam create-policy \
--policy-name LambdaSNSPublishPolicy \
--policy-document file://sns-publish-policy.json
実行ロールにカスタム管理ポリシーをアタッチする(実行ロール名、ポリシーのARN 指定)
aws iam attach-role-policy \
--role-name LambdaSNSPublishRole \
--policy-arn arn:aws:iam::123456789012:policy/LambdaSNSPublishPolicy
SNSがLambdaを呼び出すことを許可するリソースベースポリシーを作成する
(Lambda関数名、SNS Topic のARN 指定)
aws lambda add-permission \
--function-name notification-handler \
--statement-id sns-invoke \
--action lambda:InvokeFunction \
--principal sns.amazonaws.com \
--source-arn arn:aws:sns:ap-northeast-1:123456789012:application-notifications
Lambda関数を作成する(SNS Topic のARN 指定)
import boto3
import json
sns = boto3.client('sns')
def lambda_handler(event, context):
# アプリケーションイベント処理
message = {
'event': 'user_registered',
'user_id': '12345',
'timestamp': '2024-12-11T10:00:00Z'
}
sns.publish(
TopicArn='arn:aws:sns:ap-northeast-1:123456789012:application-notifications',
Message=json.dumps(message),
Subject='New User Registration'
)
パターン3:イベント駆動処理 EventBridge → SNS → ファンアウト(Email、SMS)
SNS Topic を作成する
aws sns create-topic \
--name infrastructure-alerts \
--attributes DisplayName="Infrastructure Alerts"
サブスクリプションを作成する(SNS Topic のARN、通知先エンドポイント 指定
aws sns subscribe \
--topic-arn arn:aws:sns:ap-northeast-1:123456789012:infrastructure-alerts \
--protocol email \
--notification-endpoint admin@example.com
aws sns subscribe \
--topic-arn arn:aws:sns:ap-northeast-1:123456789012:infrastructure-alerts \
--protocol sms \
--notification-endpoint +818012345678
EventBridge がSNSを呼び出すことを許可するリソースベースポリシーを作成する
(SNS Topic のARN、ポリシーファイル名 指定)
eventbridge-sns-policy.json
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowEventBridgePublish",
"Effect": "Allow",
"Principal": {
"Service": "events.amazonaws.com"
},
"Action": "SNS:Publish",
"Resource": "arn:aws:sns:ap-northeast-1:123456789012:infrastructure-alerts"
}
]
}
aws sns set-topic-attributes \
--topic-arn arn:aws:sns:ap-northeast-1:123456789012:infrastructure-alerts \
--attribute-name Policy \
--attribute-value file://eventbridge-sns-policy.json
イベントルールを作成する(イベントパターンファイル名 指定)
ec2-stopped-event-pattern.json
aws events put-rule \
--name ec2-instance-stopped \
--event-pattern file://ec2-stopped-event-pattern.json
ターゲットを追加する(ターゲットファイル名 指定)
ec2-stopped-targets.json
[
{
"Id": "1",
"Arn": "arn:aws:sns:ap-northeast-1:123456789012:infrastructure-alerts"
}
]
aws events put-targets \
--rule ec2-instance-stopped \
--targets file://ec2-stopped-targets.json
CloudFormationのサンプルコード
Terraformのサンプルコード
料金計算
| 課金項目 | 説明 |
|---|---|
| リクエスト数 | Publish APIリクエスト数 |
| 通知配信 | 配信先プロトコル別の配信数 (HTTP、Email、SMSなど) |
| データ転送 | インターネットへのデータ転送 |