SNS

【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配信ステータスログ
CloudWatch Logs優先の原則
標準メトリクス
メトリクス名説明
NumberOfMessagesPublished発行されたメッセージ数
NumberOfNotificationsFilteredOutフィルタリングで破棄された通知数
PublishSizeパブリッシュされたメッセージサイズ合計
HTTPFailureHTTPエンドポイントへの失敗通知数
HTTPSuccessHTTPエンドポイントへの成功通知数
NumberOfNotificationsDelivered配信成功通知数
NumberOfNotificationsFailed配信失敗通知数
NumberOfNotificationsFilteredOutInvalidAttributes無効属性によるフィルタ数
NumberOfNotificationsRedrivenToDLQDLQへ再投入された通知数
SMSMonthToDateSpentUSDSMS課金額(月累計)

制限値(固定値/ハードリミット/ソフトリミット)

ハードリミット制限値
メッセージサイズ最大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、通知先エンドポイント 指定)
protocolendpoint
emailメールアドレス
sms+8190xxxx(E.164形式)
lambdaLambda ARN
sqsSQS ARN
httpsHTTP エンドポイントの URL
applicationMobile push endpoint ARN
firehoseFirehose 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など)
データ転送インターネットへのデータ転送
料金計算ツール

公式ページ

AWSドキュメント SNS