目次

Amazon SNS 完全ガイド 2026

初心者から実務者向けの包括的解説

Amazon SNS(Simple Notification Service) は、「Pub/Sub メッセージングとモバイルプッシュ通知のフルマネージドサービス」 であり、1つのメッセージを複数のサブスクライバーに同時配信(Fan-out)する基幹統合サービスです。本ドキュメントは、SNSの概念・使い方・エコシステム・最新動向を体系的に解説する包括的ガイドです。

ドキュメントの目的

本ガイドは以下を対象としています。

  • 初心者向け: SNSとは何か、なぜ必要かを学びたい方
  • 開発者向け: トピック・サブスクリプション・メッセージを使いこなしたい方
  • AWS アーキテクト向け: Fan-out パターン・イベント駆動アーキテクチャを設計したい方
  • DevOps / SRE向け: CloudWatch アラーム通知・モバイルプッシュを運用したい方
  • 意思決定者向け: SNS vs EventBridge vs SQS の比較・投資判断

2026 年の SNS エコシステム

  • SNS Python SDK v3:aioboto3 による非同期対応完全
  • Message Data Protection(MDP):2025 年導入の暗号化メッセージフィルタ
  • Archive and Replay:メッセージアーカイブ・リプレイ機能(プレビュー中)
  • Token Authentication:OIDC ベースの認証(IAM 不要)
  • Cost Optimizations:バッチ API、リージョン間低遅延送信
  • Mobile Push 強化:Web Push Protocol(W3C)対応加速
  • FIFO トピック拡張:メッセージグループ化・重複排除の範囲拡大

定義

AWS 公式による定義:

“Amazon SNS is a fully managed service that provides high-throughput, push-based messaging. You can use Amazon SNS to fan out notifications to a large number of subscribers, including distributed systems and services.”What is Amazon SNS

複数の配信先(SQS・Lambda・HTTP・Email・SMS・モバイルプッシュ)に対応し、リアルタイム通知とイベント駆動アーキテクチャの中核となります。

エディション・デプロイメントオプション

  • Standard SNS(フルマネージド):AWS が提供する標準 SNS サービス
  • SNS FIFO トピック:メッセージ順序・重複排除を保証
  • SNS in VPC(VPC Endpoint):プライベートネットワーク内での SNS 利用

目次

  1. 概要
  2. SNS が解決する課題
  3. 主な特徴
  4. アーキテクチャ(Topic・Subscription・Publisher・Subscriber)
  5. トピックタイプ(Standard・FIFO)
  6. サブスクリプションプロトコル(SQS・Lambda・HTTP・Email・SMS・Mobile Push・Kinesis)
  7. 主要ユースケース(10+)
  8. メッセージフィルタリング
  9. メッセージアトリビュート
  10. SMS(Promotional・Transactional・SMS Originating Number)
  11. Mobile Push(APNs・FCM・ADM)
  12. SNS-SQS ファンアウトパターン
  13. SNS + Kinesis Data Firehose(S3 アーカイブ)
  14. DLQ(Dead Letter Queue)
  15. セキュリティ(IAM・Resource Policy・KMS・VPC Endpoint)
  16. CloudWatch メトリクス
  17. 他の類似ツールとの比較
  18. クライアントとエコシステム(CLI・SDK・IaC)
  19. ベストプラクティス
  20. トラブルシューティング
  21. 2025-2026 最新動向
  22. 学習リソース
  23. 実装例・活用シーン
  24. 導入ロードマップ
  25. 実装チェックリスト
  26. まとめ
  27. 参考文献

概要

初心者向けメモ: SNS は「メッセージを送る」ツールではなく、「1つのメッセージを複数の異なるシステムに同時に配信する」Pub/Sub(パブリッシャー・サブスクライバー)の仲介役です。発行元(Publisher)がトピックにメッセージを送ると、そのトピックをリッスンしているすべてのサブスクライバーが同時にそのメッセージを受け取ります。これを 「Fan-out」(扇状に広がる配信) と呼びます。

Amazon SNS は、メッセージング・通知・イベント駆動アーキテクチャの中核サービスです。公式ドキュメント(SNS Developer Guide)に基づくと、単なる通知ツールではなく、マイクロサービス・分散システムの疎結合連携 を実現する統合基盤として機能します。

SNS の位置づけ

【図1】AWS メッセージング・イベント駆動スタックにおける SNS の位置:

graph TD
    EventSource["イベント発生元<br/>EC2 / S3 / Lambda / Custom"]
    
    SNS["Amazon SNS<br/>Pub/Sub Topic"]
    
    SQS["Amazon SQS<br/>Durable Queue"]
    Lambda["AWS Lambda<br/>Event Handler"]
    HTTP["HTTP/HTTPS<br/>Webhook"]
    Email["Email<br/>Direct Send"]
    SMS["SMS / Mobile Push<br/>Transactional"]
    KDF["Kinesis Data Firehose<br/>Archive to S3"]
    
    EventSource -->|Publish| SNS
    
    SNS -->|Fan-out| SQS
    SNS -->|Invoke| Lambda
    SNS -->|HTTP POST| HTTP
    SNS -->|Send| Email
    SNS -->|Send| SMS
    SNS -->|Stream| KDF
    
    SQS -->|Consume| Consumer["Worker / Process"]
    Lambda -->|Execute| Handler["Function"]
    HTTP -->|Process| External["External API"]
    KDF -->|Archive| S3["Amazon S3<br/>Data Lake"]

SNS が解決する課題

課題 SNS での解決方法 メリット
1対多の通知が複雑 トピック経由で複数サブスクライバーに同時配信 発行元が配信先を意識しない疎結合性
複数の配信チャネルを管理 Email・SMS・プッシュ・SQS を統一 API で送信 各プロトコル個別管理の複雑さ排除
イベント駆動ロジックの耦合 Fan-out パターンでワーカーを並列化 サブスクライバーの追加削除が容易
メッセージの重複送信 SNS FIFO で順序と重複排除を保証 金融・取引ドメインの要件に対応
フィルタリングの複雑さ メッセージ属性ベースの選択的配信 大量メッセージから関心あるもののみ受信
モバイルプッシュの統合 APNs・FCM・ADM を統一管理 複数プラットフォームの SDK 管理負荷削減
配信失敗への対応 DLQ・再試行ポリシーで信頼性確保 重要な通知の到達を保証

主な特徴

特徴 説明
Pub/Sub メッセージング Publisher がトピックに送信、複数 Subscriber が受信
高スループット・低レイテンシ 秒単位でマイオンのメッセージを処理可能
マルチプロトコル対応 SQS・Lambda・HTTP・Email・SMS・モバイルプッシュ・Kinesis Data Firehose
メッセージフィルタリング サブスクライバーごとに受信条件を指定可能
FIFO トピック メッセージ順序・重複排除を保証
Fan-out パターン 1つのメッセージを複数の独立したワーカーに分配
メッセージアトリビュート JSON 形式のメタデータでメッセージに属性を付加
CloudWatch 統合 メトリクス・ログ・アラーム機能
VPC Endpoint 対応 プライベートネットワーク内での利用が可能
IAM・KMS 統合 ロールベース制御・暗号化
リスト価格(2026) API 呼び出し $0.50/100万通知

アーキテクチャ

初心者向けメモ: SNS は大きく分けて 4 つの要素からなります。Publisher(発行元) がメッセージを Topic(トピック) に送ると、Topic に登録された複数の Subscription(サブスクリプション) が同時にそのメッセージを受け取り、各 Subscriber(受信者) に配信されます。

【図2】SNS の 4 層アーキテクチャ:

graph TD
    subgraph Pub["Publisher層<br/>メッセージ発行元"]
        EC2["EC2 Instance"]
        S3["S3 Events"]
        Lambda["Lambda Function"]
        CustomApp["Custom Application"]
    end
    
    subgraph Core["SNS Core層"]
        Topic["Topic<br/>トピック"]
    end
    
    subgraph Sub["Subscription層<br/>購読設定"]
        Sub1["Subscription-1<br/>Filter: OrderStatus=Created"]
        Sub2["Subscription-2<br/>Filter: OrderStatus=Created"]
        Sub3["Subscription-3<br/>No Filter"]
    end
    
    subgraph Endpoints["Endpoint層<br/>最終受信者"]
        SQS["SQS Queue<br/>Worker 1"]
        LambdaH["Lambda Handler<br/>Worker 2"]
        HTTP["HTTP/Webhook<br/>External API"]
        Email["Email Service<br/>Admin Notification"]
        SMS["SMS Service<br/>Emergency Alert"]
        FirehoseS3["Kinesis Firehose→S3<br/>Data Archive"]
    end
    
    Pub -->|Publish| Topic
    Topic -->|Distribute| Sub1
    Topic -->|Distribute| Sub2
    Topic -->|Distribute| Sub3
    
    Sub1 -->|Route| SQS
    Sub2 -->|Route| LambdaH
    Sub3 -->|Route| HTTP
    Sub3 -->|Route| Email
    Sub3 -->|Route| SMS
    Sub3 -->|Route| FirehoseS3

4つのコアコンポーネント

1. Topic(トピック)

  • メッセージの集約ポイント
  • 複数の Subscription を登録可能
  • ARN(Amazon Resource Name)で一意に識別
  • Standard または FIFO タイプ

2. Publisher(発行元)

  • PublishMessage API でトピックにメッセージを送信
  • 配信先を意識しない(トピックのみ指定)
  • SDK・CLI・CloudWatch イベント・S3 イベント等様々な発行元

3. Subscription(サブスクリプション)

  • Topic と Endpoint(受信者)をつなぐ設定オブジェクト
  • フィルタリングポリシー(メッセージ属性ベース)を定義可能
  • サブスクリプション ARN で管理
  • Endpoint の生存確認(confirmation)

4. Subscriber(受信者)

  • 実際にメッセージを受け取るエンドポイント
  • SQS キュー・Lambda・HTTP URL・Email・SMS・モバイルプッシュ等

トピックタイプ

Standard トピック(デフォルト)

  • メッセージ順序:保証しない
  • 重複:発生する可能性あり
  • スループット:無制限
  • 配信回数:最大 1 回(At-most-once)

特徴:

  • 高スループット:秒単位で数百万メッセージ処理
  • 低レイテンシ:ミリ秒単位の配信
  • 順序不保証:メッセージ到着順序が変わる可能性
  • 重複配信の可能性:同じメッセージが複数回配信される場合あり

適用シーン:

  • インフラ監視・アラート(順序不要)
  • ユーザー通知・メール送信(多少の重複許容)
  • Analytics イベント(概算で十分)

FIFO トピック

  • メッセージ順序:严密に保証
  • 重複:排除(同じメッセージは 1 回のみ)
  • スループット:制限あり(300 msg/sec 標準)
  • 配信回数:Exactly-once-per-group

特徴:

  • 順序保証:Message Group ID で同一グループ内の順序を保証
  • 重複排除:Deduplication ID で同一メッセージの重複を排除
  • スループット制限:1 トピックあたり 300 msg/sec(スケーリング可能)
  • SQS FIFO との相性:SQS FIFO サブスクリプションのみ対応

適用シーン:

  • 金融取引:順序が重要(注文 → 決済 → 配送)
  • 在庫管理:重複排除が必須(同一注文の重複実行防止)
  • ワークフロー:複数ステップを厳密に順序化

FIFO の制限:

  • SQS Standard・Lambda・HTTP のサブスクリプション不可
  • SQS FIFO キューのみサブスクライブ可能
  • スループット制限(調整可能)

Standard vs FIFO 比較表

観点 Standard FIFO
メッセージ順序 保証なし Group ID で保証
重複排除 なし Deduplication ID で排除
スループット 無制限 300 msg/sec 標準
レイテンシ 最低(ミリ秒) やや高い
対応 Subscriber SQS・Lambda・HTTP・Email・SMS・プッシュ SQS FIFO のみ
価格 基本料金 Standard の 50% 割増
推奨用途 通知・アラート・分析 金融・トランザクション・在庫

サブスクリプションプロトコル

SNS では、トピックに複数のプロトコルで同時にサブスクライブ可能。各プロトコルの詳細:

1. SQS(Amazon Simple Queue Service)

  • Protocol: sqs
  • Endpoint: arn:aws:sqs:region:account:queue-name
  • 特徴: Durable queue として機能。バッファリング・リトライ

用途:

  • ワーカープロセスへの非同期配信
  • Fan-out パターンの実現

設定例(AWS CLI):

aws sns subscribe \
  --topic-arn arn:aws:sns:us-east-1:123456789012:orders \
  --protocol sqs \
  --notification-endpoint arn:aws:sqs:us-east-1:123456789012:order-queue

2. AWS Lambda

  • Protocol: lambda
  • Endpoint: arn:aws:lambda:region:account:function:function-name
  • 特徴: イベント駆動で即座に関数実行

用途:

  • リアルタイムデータ処理
  • サーバーレス ワークフロー自動化

3. HTTP / HTTPS

Protocol: http / https
Endpoint: https://example.com/notify
特徴: REST API・Webhook 形式

用途:

  • 外部 API 連携
  • IFTTT・Zapier 等のサードパーティ自動化

4. Email / Email-JSON

  • Protocol: email / email-json
  • Endpoint: user@example.com
  • 特徴: 直接メール送信

用途:

  • 管理者通知
  • ユーザー周知メール

5. SMS(Short Message Service)

  • Protocol: sms
  • Endpoint: +1234567890(E.164 形式)
  • 特徴: テキストメッセージ配信

用途:

  • 緊急通知
  • OTP(One Time Password)配信

6. モバイルプッシュ通知

  • Protocol: application
  • Endpoint: arn:aws:sns:region:account:app/GCM/MyApplication/12345678-1234
  • 特徴: iOS(APNs)・Android(FCM)・Amazon(ADM)対応

用途:

  • アプリ内プッシュ通知
  • リアルタイムユーザー通知

7. Amazon Kinesis Data Firehose

  • Protocol: firehose
  • Endpoint: arn:aws:kinesis:region:account:deliverystream/stream-name
  • 特徴: S3・Redshift・Datadog 等へのアーカイブ

用途:

  • 監査ログの長期保存
  • 分析用データ湖へのストリーミング

サブスクリプションプロトコル一覧表

プロトコル エンドポイント 配信保証 用途
SQS キュー ARN At-least-once バッファリング・並列処理
Lambda 関数 ARN 同期実行 リアルタイム処理
HTTP/HTTPS URL HTTP Status Webhook・外部 API
Email メールアドレス ベストエフォート 管理者通知
SMS 電話番号 キャリア依存 緊急通知
Mobile Push デバイストークン プラットフォーム依存 アプリ通知
Kinesis Firehose Stream ARN At-least-once アーカイブ・分析

主要ユースケース

初心者向けメモ: SNS は「通知」のイメージが強いですが、実はもっと広い用途で使われます。ここでは実務でよくある 10 以上のユースケースを整理します。

1. イベント駆動アーキテクチャ(Fan-out パターン)

EC サイトの注文確定イベントをトリガーに、複数の独立したドメインが並列で処理。

ユースケース:

注文確定イベント → SNS Topic
    ├→ SQS → 在庫更新 Lambda
    ├→ SQS → 配送依頼 Lambda
    ├→ SQS → Analytics イベント
    └→ Email → 顧客確認メール

メリット:

  • Publisher(注文サービス)が配信先を意識しない
  • Subscriber 追加・削除が容易
  • 各ドメインが独立して開発・スケール

2. CloudWatch アラーム通知

インフラ監視アラームの複数チャネル同時通知。

ユースケース:

CloudWatch Alarm(CPU > 80%)→ SNS Topic
    ├→ PagerDuty(インシデント自動開始)
    ├→ Lambda → Slack(エンジニア通知)
    ├→ Email(管理者報告)
    └→ SMS(On-call 携帯通知)

メリット:

  • 複数チャネルの同時配信で見落とし防止
  • フィルタリングで重大度別対応

3. モバイルプッシュ通知

iOS・Android への統一 API によるプッシュ配信。

ユースケース:

ニュースアプリの速報配信
    → SNS Topic
    ├→ iOS(APNs): iPhone ユーザー
    ├→ Android(FCM): Android ユーザー
    └→ Amazon Device(ADM): Kindle ユーザー

メリット:

  • SDK ごとに異なるプロトコルを統一管理
  • デバイストークン管理を SNS に委譲

4. SMS トランザクション通知

OTP・重要確認・緊急通知の SMS 配信。

ユースケース:

  • ユーザーログイン試行 → SNS Topic(SMS protocol)
  • → 2FA OTP を SMS で配信

メリット:

  • トランザクション専用レート・信頼性
  • 配信レポート・メタデータ取得

5. Email マーケティング・通知

直接メール送信(SES と異なり SNS は通知寄り)。

ユースケース:

  • ユーザーサインアップ → SNS Email
  • → 登録確認メール送信

6. データ統合・アーカイブ

SNS → Kinesis Firehose → S3 で監査ログ・分析データを蓄積。

ユースケース:

アプリログイベント → SNS Topic → Kinesis Firehose
    ├→ S3 データレイク(Parquet フォーマット)
    ├→ Redshift(リアルタイム分析)
    └→ Datadog(外部監視)

7. マイクロサービス間の非同期通信

サービス間の疎結合なメッセージング。

ユースケース:

OrderService → SNS → {PaymentService, ShippingService, NotificationService}

メリット:

  • サービス間の直接依存を排除
  • 各サービスが独立してスケール

8. リアルタイム分析イベント

Web アナリティクス・ユーザー行動ログの即座処理。

ユースケース:

ユーザアクション → SNS → Kinesis Data Analytics
    ├→ リアルタイムダッシュボード
    ├→ 異常検知
    └→ 機械学習 パイプライン

9. DevOps・CI/CD パイプライン

デプロイ完了・テスト結果・ビルドイベント通知。

ユースケース:

CodePipeline Success → SNS Topic
    ├→ Lambda → Slack(デプロイ完了報告)
    ├→ Lambda → JIRA(Ticket 更新)
    └→ Email(Product Manager 報告)

10. 金融・取引ワークフロー(FIFO)

トランザクション順序・重複排除が必須の金融処理。

ユースケース:

  • 取引システム → SNS FIFO Topic
  • → SQS FIFO → 注文処理(順序厳密・重複排除)
  • → SQS FIFO → 決済処理
  • → SQS FIFO → 配送処理

メリット:

  • メッセージ順序の厳密保証
  • 重複実行防止(Deduplication ID)

ユースケース適性マトリクス

ワークロード SNS 適性 備考
イベント駆動・Fan-out ★★★★★ SNS の最強ユースケース
通知・アラート ★★★★★ 複数チャネル対応
モバイルプッシュ ★★★★★ iOS・Android 統一管理
SMS 配信 ★★★★ トランザクション向け
Email 配信 ★★★ SES の方が高機能
データアーカイブ ★★★★ Firehose 統合
リアルタイム分析 ★★★★ Kinesis・Lambda 組み合わせ
金融トランザクション ★★★★ FIFO トピック使用時
メッセージキュー ★★ SQS の方が適切
複雑なイベントルーティング ★★ EventBridge の方が高機能

メッセージフィルタリング

SNS のメッセージフィルタリング(Filter Policy)は、トピックに送られた全メッセージのうち、特定の条件を満たすメッセージのみをサブスクライバーに配信 する機能です。

フィルタリングの仕組み

ユースケース:

注文トピックに以下のメッセージが送られる:

Message 1: {"type": "order", "status": "created", "amount": 100}
Message 2: {"type": "order", "status": "cancelled", "amount": 50}
Message 3: {"type": "payment", "status": "processed"}

SQS-A(新規注文処理 Worker):
フィルター: {"type": ["order"], "status": ["created"]}
→ Message 1 のみ受信 ✅

SQS-B(キャンセル処理 Worker):
フィルター: {"type": ["order"], "status": ["cancelled"]}
→ Message 2 のみ受信 ✅

SQS-C(全ログ記録):
フィルター: なし(全メッセージ受信)
→ Message 1, 2, 3 すべて受信 ✅

SQS-D(支払い処理):
フィルター: {"type": ["payment"]}
→ Message 3 のみ受信 ✅

フィルタポリシー JSON 形式

基本形式:

{
  "attribute_name": ["value1", "value2"],
  "numeric_attribute": [{"numeric": [">", 100]}],
  "exists_attribute": [{"exists": true}]
}

実装例:

{
  "type": ["order"],
  "status": ["created", "pending"],
  "amount": [{"numeric": [">", 1000]}],
  "priority": [{"exists": true}]
}

フィルタリング演算子

演算子 説明
等号(文字列) 完全一致 {"type": ["order"]}
複数値 OR 複数値のいずれか {"status": ["created", "pending"]}
数値比較 >, <, >=, <=, = {"amount": [{"numeric": [">", 100]}]}
Prefix 文字列の開始 {"uuid": [{"prefix": "abc"}]}
Exists 属性の存在 {"priority": [{"exists": true}]}
Anything-but 除外 {"status": [{"anything-but": "cancelled"}]}

フィルタリングの実装シナリオ

シナリオ 1:高額注文のみ処理

{
  "type": ["order"],
  "amount": [{"numeric": [">=", 10000]}]
}

シナリオ 2:エラーレベルが CRITICAL のみ通知

{
  "level": ["CRITICAL"],
  "source": ["system", "infrastructure"]
}

シナリオ 3:特定リージョンを除外

{
  "region": [{"anything-but": "us-west-2"}]
}

メッセージアトリビュート

SNS メッセージはボディ以外に、構造化されたメタデータ Message Attributes(メッセージアトリビュート) を添付可能。フィルタリング・ルーティング・メタデータ追跡に利用。

アトリビュートの種類

説明
String 文字列値 order_id: “ORD-12345”
String.Array 文字列配列 tags: ["urgent", "customer"]
Number 数値 amount: 1500.50
Binary バイナリデータ 画像・ファイル

実装例(Python SDK v3)

import boto3

sns = boto3.client('sns')

# メッセージアトリビュート付きで発行
response = sns.publish(
    TopicArn='arn:aws:sns:us-east-1:123456789012:orders',
    Message='Order confirmed',
    MessageAttributes={
        'type': {
            'DataType': 'String',
            'StringValue': 'order'
        },
        'status': {
            'DataType': 'String',
            'StringValue': 'created'
        },
        'amount': {
            'DataType': 'Number',
            'StringValue': '1500'
        },
        'priority': {
            'DataType': 'String',
            'StringValue': 'high'
        }
    }
)

メッセージアトリビュートのベストプラクティス

活用シーン:

  • フィルタリング条件に使用
  • ダウンストリーム処理での判定ロジック簡素化
  • メッセージの出所・優先度・言語等メタデータ

非推奨:

  • 大きなデータ(Message Body を使用)
  • 機密情報(暗号化が必要)

SMS

SNS SMS は、トランザクション SMS(OTP・確認コード)と Promotional SMS(マーケティング) の 2 種類をサポート。

SMS の 2 つのカテゴリ

Transactional SMS

  • 用途: OTP・2FA・決済確認・配送通知等
  • レート: 高(優先配信)
  • 送信制限: トランザクション専用レート
  • 配信保証: 最優先

実装例:

response = sns.publish(
    PhoneNumber='+1234567890',
    Message='Your OTP is: 123456',
    MessageAttributes={
        'AWS.SNS.SMS.SenderID': {
            'DataType': 'String',
            'StringValue': 'MYAPP'
        },
        'AWS.SNS.SMS.SMSType': {
            'DataType': 'String',
            'StringValue': 'Transactional'  # ← Transactional
        }
    }
)

Promotional SMS

  • 用途: マーケティング・キャンペーン・新製品通知
  • レート: 低(ベストエフォート)
  • 送信制限: プロモーション専用レート
  • 配信保証: 標準

実装例:

response = sns.publish(
    PhoneNumber='+1234567890',
    Message='Flash sale: 50% off all items!',
    MessageAttributes={
        'AWS.SNS.SMS.SMSType': {
            'DataType': 'String',
            'StringValue': 'Promotional'  # ← Promotional
        }
    }
)

SMS Originating Number

送信元番号(From)の設定。デフォルトは AWS 提供のランダム番号。

タイプ 説明 コスト
Short Code 5-6 桁短縮番号(米国)
Long Code 通常の電話番号 標準
Sender ID ブランド名(国による)

SMS 配信レート・価格(2026)

地域 レート
USA $0.0075/SMS
Canada $0.0085/SMS
UK $0.0065/SMS
Australia $0.0095/SMS
日本 $0.01/SMS

Mobile Push

SNS Mobile Push は、iOS(APNs)・Android(FCM)・Amazon デバイス(ADM) のプッシュ通知を統一 API で配信。

プラットフォーム別対応

iOS(Apple Push Notification Service - APNs)

  • デバイストークン形式: UUID
  • 証明書: Apple Developer Certificate(.p8)
  • JSON フォーマット: APNs JSON ペイロード

設定手順:

  1. Apple Developer Account で APNs 証明書を生成
  2. AWS SNS で Platform Application を作成
  3. APNs 証明書をアップロード

Android(Firebase Cloud Messaging - FCM)

  • デバイストークン形式: FCM Token
  • 認証: Firebase Service Account JSON
  • JSON フォーマット: FCM JSON ペイロード

Amazon Device(ADM)

  • デバイストークン形式: Amazon Device Token
  • 認証: Client ID・Client Secret

Platform Application と Endpoint の関係

graph TD
    SNS["Amazon SNS"]
    PlatformApp["Platform Application<br/>MyApp-iOS"]
    Endpoint1["Endpoint-1<br/>Device Token ABC"]
    Endpoint2["Endpoint-2<br/>Device Token DEF"]
    Device1["iPhone 1"]
    Device2["iPhone 2"]
    
    SNS -->|Create| PlatformApp
    PlatformApp -->|Register| Endpoint1
    PlatformApp -->|Register| Endpoint2
    Endpoint1 -->|Push| Device1
    Endpoint2 -->|Push| Device2

プッシュ送信実装例(Python)

import boto3

sns = boto3.client('sns', region_name='us-east-1')

# 特定デバイスへのプッシュ
response = sns.publish(
    TargetArn='arn:aws:sns:us-east-1:123456789012:app/GCM/MyApp/a1b2c3d4',
    Message='Breaking news: Market rally!',
    MessageAttributes={
        'AWS.SNS.MOBILE.APNS_SANDBOX': {
            'DataType': 'String.Array',
            'StringValue': '["true"]'  # テスト環境
        }
    },
    MessageStructure='json'
)

プッシュ通知のベストプラクティス

推奨:

  • デバイストークン定期更新(有効期限管理)
  • 地域別・デバイス別のセグメント分けフィルタリング
  • ユーザー許可ベースの配信

非推奨:

  • スパム的なプッシュ連続配信
  • ユーザー許可なしの送信

SNS-SQS ファンアウトパターン

最も実用的で一般的な SNS 活用パターン。SNS トピックを複数の SQS キューにファンアウトして、各ワーカーが独立して処理。

ファンアウトパターンの仕組み

graph TD
    Publisher["Publisher<br/>Order Service"]
    SNSTopic["SNS Topic<br/>order-created"]
    
    SQS1["SQS Queue<br/>inventory-queue"]
    SQS2["SQS Queue<br/>shipping-queue"]
    SQS3["SQS Queue<br/>billing-queue"]
    SQS4["SQS Queue<br/>analytics-queue"]
    
    Worker1["Worker-1<br/>Inventory Service"]
    Worker2["Worker-2<br/>Shipping Service"]
    Worker3["Worker-3<br/>Billing Service"]
    Worker4["Worker-4<br/>Analytics"]
    
    Publisher -->|Publish| SNSTopic
    SNSTopic -->|Fan-out| SQS1
    SNSTopic -->|Fan-out| SQS2
    SNSTopic -->|Fan-out| SQS3
    SNSTopic -->|Fan-out| SQS4
    
    SQS1 -->|Consume| Worker1
    SQS2 -->|Consume| Worker2
    SQS3 -->|Consume| Worker3
    SQS4 -->|Consume| Worker4

設定手順(CloudFormation)

# SNS Topic
OrderTopic:
  Type: AWS::SNS::Topic
  Properties:
    TopicName: order-created

# SQS キュー 1: 在庫更新
InventoryQueue:
  Type: AWS::SQS::Queue
  Properties:
    QueueName: inventory-queue

# SQS キュー 2: 配送処理
ShippingQueue:
  Type: AWS::SQS::Queue
  Properties:
    QueueName: shipping-queue

# SNS → SQS1 のサブスクリプション
InventorySub:
  Type: AWS::SNS::Subscription
  Properties:
    Protocol: sqs
    TopicArn: !Ref OrderTopic
    Endpoint: !GetAtt InventoryQueue.Arn
    FilterPolicy:
      type:
        - order
      status:
        - created

# SNS → SQS2 のサブスクリプション
ShippingSub:
  Type: AWS::SNS::Subscription
  Properties:
    Protocol: sqs
    TopicArn: !Ref OrderTopic
    Endpoint: !GetAtt ShippingQueue.Arn

# SQS キューポリシー(SNS から受信許可)
InventoryQueuePolicy:
  Type: AWS::SQS::QueuePolicy
  Properties:
    Queues:
      - !Ref InventoryQueue
    PolicyText:
      Statement:
        - Effect: Allow
          Principal:
            Service: sns.amazonaws.com
          Action: sqs:SendMessage
          Resource: !GetAtt InventoryQueue.Arn
          Condition:
            ArnEquals:
              aws:SourceArn: !Ref OrderTopic

ファンアウトパターンのメリット

Publisher と Subscriber の疎結合

  • Publisher はトピックのみ指定
  • Subscriber 追加・削除が容易
  • 各サービスが独立して開発・スケール

並列処理

  • 複数ワーカーが同時に異なるタスク実行
  • 全体スループット向上

リトライ・デッドレター

  • SQS のリトライ・DLQ メカニズム活用

ファンアウトパターンの注意点

順序不保証

  • SNS Standard では メッセージ順序が変わる場合あり
  • 順序が必須なら FIFO トピック+SQS FIFO 使用

重複配信の可能性

  • SNS が複数回配信する可能性あり
  • Consumer 側で冪等性を確保

SNS + Kinesis Data Firehose

SNS メッセージを Kinesis Data Firehose 経由で S3・Redshift・Datadog 等へアーカイブ・分析

アーキテクチャ

graph TD
    EventSource["Event Source<br/>Application / Service"]
    SNS["SNS Topic"]
    Firehose["Kinesis Data Firehose"]
    S3["Amazon S3<br/>Data Lake"]
    Redshift["Amazon Redshift<br/>Analytics"]
    Datadog["Datadog<br/>Monitoring"]
    
    EventSource -->|Publish| SNS
    SNS -->|Stream| Firehose
    Firehose -->|Archive| S3
    Firehose -->|Load| Redshift
    Firehose -->|Forward| Datadog

設定例(CloudFormation)

# SNS Topic
AuditLogTopic:
  Type: AWS::SNS::Topic
  Properties:
    TopicName: audit-logs

# Kinesis Data Firehose
AuditLogFirehose:
  Type: AWS::KinesisFirehose::DeliveryStream
  Properties:
    DeliveryStreamName: audit-log-stream
    S3DestinationConfiguration:
      BucketARN: !Sub 'arn:aws:s3:::${AuditBucket}'
      Prefix: 'audit-logs/'
      BufferingHints:
        SizeInMBs: 128
        IntervalInSeconds: 3600
      CompressionFormat: GZIP
      ProcessingConfiguration:
        Enabled: false

# SNS → Firehose サブスクリプション
FirehoseSub:
  Type: AWS::SNS::Subscription
  Properties:
    Protocol: firehose
    TopicArn: !Ref AuditLogTopic
    Endpoint: !Sub 'arn:aws:kinesis:${AWS::Region}:${AWS::AccountId}:deliverystream/${AuditLogFirehose}'

使用例

シナリオ:セキュリティ監査ログのアーカイブ

セキュリティイベント
    ↓
SNS Topic(audit-logs)
    ↓
Kinesis Data Firehose
    ├→ S3(Parquet フォーマット)
    ├→ Redshift(リアルタイム分析テーブル)
    └→ Datadog(セキュリティ監視)

メリット:

  • 全イベントの永続記録(コンプライアンス)
  • リアルタイムと長期分析の両立
  • Redshift で複雑な分析可能

DLQ(Dead Letter Queue)

配信失敗メッセージの「捨てる」のではなく、Dead Letter Queue に送ってあとで分析・復旧できる仕組み。

DLQ の動作

graph TD
    SNS["SNS Topic"]
    Sub["Subscription"]
    Endpoint["Endpoint<br/>Lambda / SQS"]
    Success["Success Path"]
    Failure["Failure after Retry"]
    DLQ["DLQ<br/>Failed Messages"]
    
    SNS -->|Publish| Sub
    Sub -->|Deliver| Endpoint
    
    Endpoint -->|Success| Success
    Endpoint -->|Failure| Retry["Retry<br/>3x"]
    Retry -->|Still Fail| DLQ
    DLQ -->|Monitor / Investigate| Analysis["Root Cause Analysis"]

DLQ の設定(Lambda サブスクリプション)

import boto3

sns = boto3.client('sns')
sqs = boto3.client('sqs')

# DLQ 作成
dlq_response = sqs.create_queue(QueueName='lambda-dlq')
dlq_arn = sqs.get_queue_attributes(
    QueueUrl=dlq_response['QueueUrl'],
    AttributeNames=['QueueArn']
)['Attributes']['QueueArn']

# SNS → Lambda サブスクリプションを DLQ 付きで作成
sns.subscribe(
    TopicArn='arn:aws:sns:us-east-1:123456789012:orders',
    Protocol='lambda',
    Endpoint='arn:aws:lambda:us-east-1:123456789012:function:OrderProcessor',
    Attributes={
        'RedrivePolicy': {
            'deadLetterTargetArn': dlq_arn
        }
    }
)

DLQ の活用シーン

トラブルシューティング

  • 配信失敗の原因調査
  • メッセージの再送処理

監視・アラート

  • DLQ にメッセージが入ったら Slack 通知
  • エラー率の可視化

セキュリティ

SNS では複数の層でセキュリティを確保:IAM ロールベース・リソースポリシー・KMS 暗号化・VPC Endpoint

1. IAM(Identity and Access Management)

最小権限原則に基づいたアクセス制御。

例:Publisher ロール

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "sns:Publish"
      ],
      "Resource": "arn:aws:sns:us-east-1:123456789012:orders"
    }
  ]
}

例:Subscriber ロール(SQS キュー)

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "sqs:ReceiveMessage",
        "sqs:DeleteMessage",
        "sqs:GetQueueAttributes"
      ],
      "Resource": "arn:aws:sqs:us-east-1:123456789012:order-queue"
    }
  ]
}

2. Resource Policy

トピックレベルのアクセス制御。

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::123456789012:user/app-publisher"
      },
      "Action": "sns:Publish",
      "Resource": "arn:aws:sns:us-east-1:123456789012:orders"
    },
    {
      "Effect": "Deny",
      "Principal": "*",
      "Action": "sns:*",
      "Resource": "*",
      "Condition": {
        "StringNotEquals": {
          "aws:SecureTransport": "true"
        }
      }
    }
  ]
}

3. KMS(Key Management Service)暗号化

トピックのメッセージを KMS キーで暗号化。

import boto3

sns = boto3.client('sns')
kms = boto3.client('kms')

# KMS キー作成
key_response = kms.create_key(
    Description='SNS Message Encryption'
)
key_id = key_response['KeyMetadata']['KeyId']

# SNS トピック作成(KMS 暗号化)
response = sns.create_topic(
    Name='secure-orders',
    Attributes={
        'KmsMasterKeyId': key_id
    }
)

# 暗号化されたメッセージ発行
sns.publish(
    TopicArn=response['TopicArn'],
    Message='Sensitive order data',
    MessageAttributes={...}
)

4. VPC Endpoint

プライベートネットワーク内での SNS 利用。AWS 提供のインターネット経由を回避。

SNSEndpoint:
  Type: AWS::EC2::VPCEndpoint
  Properties:
    VpcEndpointType: Interface
    ServiceName: !Sub 'com.amazonaws.${AWS::Region}.sns'
    VpcId: !Ref VPC
    SubnetIds:
      - !Ref PrivateSubnet1
      - !Ref PrivateSubnet2
    SecurityGroupIds:
      - !Ref EndpointSecurityGroup

5. トランザイトイン・トランザイトアウト

暗号化を強制:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Deny",
      "Principal": "*",
      "Action": "sns:*",
      "Resource": "arn:aws:sns:*:*:*",
      "Condition": {
        "Bool": {
          "aws:SecureTransport": "false"
        }
      }
    }
  ]
}

セキュリティベストプラクティス

実装すべき:

  • IAM によるアクセス制御(最小権限)
  • KMS 暗号化(機密データ)
  • VPC Endpoint(プライベートネットワーク)
  • HTTPS/TLS 強制(Resource Policy)

避けるべき:

  • ワイルドカード権限(sns:*
  • 平文での機密データ送信
  • パブリックトピック(誰でも Publish 可能)

CloudWatch メトリクス

SNS は CloudWatch とネイティブ統合。メトリクス・ログ・ダッシュボードで可視化。

主要メトリクス

メトリクス 説明 ユースケース
NumberOfMessagesPublished 発行されたメッセージ数 スループット監視
NumberOfNotificationsFailed 配信失敗数 エラー率監視
NumberOfNotificationsDelivered 正常配信数 配信成功率
PublishSize メッセージサイズ ペイロード分析

ダッシュボード・アラーム例(CloudFormation)

SNSDashboard:
  Type: AWS::CloudWatch::Dashboard
  Properties:
    DashboardName: SNS-Monitoring
    DashboardBody: !Sub |
      {
        "widgets": [
          {
            "type": "metric",
            "properties": {
              "metrics": [
                ["AWS/SNS", "NumberOfMessagesPublished", {"stat": "Sum"}],
                ["AWS/SNS", "NumberOfNotificationsFailed", {"stat": "Sum"}],
                ["AWS/SNS", "NumberOfNotificationsDelivered", {"stat": "Sum"}]
              ],
              "period": 60,
              "stat": "Average",
              "region": "${AWS::Region}"
            }
          }
        ]
      }

SNSFailureAlarm:
  Type: AWS::CloudWatch::Alarm
  Properties:
    AlarmName: SNS-Delivery-Failures
    MetricName: NumberOfNotificationsFailed
    Namespace: AWS/SNS
    Statistic: Sum
    Period: 300
    EvaluationPeriods: 1
    Threshold: 10
    ComparisonOperator: GreaterThanThreshold
    AlarmActions:
      - !Ref AlertTopic

他の類似ツールとの比較

初心者向けメモ: AWS 内にもメッセージングツールが複数あります。SNS・SQS・EventBridge それぞれの立ち位置を整理します。

1. SNS vs SQS

最もよく比較される 2 つのサービス。

観点 SNS SQS
パターン Pub/Sub(1 → 多) Queue(1 → 1)
ユースケース Fan-out・通知 バッファリング・非同期処理
配信先 複数(SQS・Lambda・HTTP・Email・SMS) 1 つのキュー
メッセージ保持 なし(即座配信) 最大 14 日
順序保証 Standard は不可、FIFO は可 Standard は不可、FIFO は可
スケーラビリティ 無制限 キューあたり制限
推奨用途 通知・イベント発行 ワーカーキュー・リトライ

使い分け:

  • 複数サービスに同時配信: SNS
  • 1つのキューでバッファリング: SQS
  • SNS → SQS: Fan-out パターンの最適解

2. SNS vs EventBridge

イベント駆動アーキテクチャでの比較。

観点 SNS EventBridge
対象 メッセージング イベント駆動
ルーティング トピックベース ルール・パターンマッチング
フィルタリング メッセージ属性ベース 豊富(JSON パス・プレフィックス等)
統合サービス数 少ない 90+ AWS サービス対応
複雑なワークフロー 不得意 得意
推奨用途 シンプルな Fan-out 複雑なイベントルーティング

使い分け:

  • シンプルな 1 対多: SNS
  • 複雑なイベントルーティング: EventBridge

3. SNS vs Kinesis

リアルタイムストリーミングでの比較。

観点 SNS Kinesis Data Streams
用途 通知・メッセージング リアルタイムストリーミング分析
スケール トピック制限なし シャード制限あり(スケール可)
順序保証 FIFO で可 シャードあたり保証
保持期間 なし 24 時間(延長可)
コンシューマー数 無制限(Fan-out) シャードあたり制限
推奨用途 イベント通知 データストリーム処理

4. SNS vs Kafka(外部比較)

セルフホスト型との比較。

観点 SNS Apache Kafka
運用 フルマネージド セルフマネージド
初期セットアップ 即座 複雑
スケール AWS が担当 自前で管理
柔軟性
コスト 従量課金 インフラコスト
学習曲線

5. SNS vs Twilio(外部比較:SMS)

SMS 配信での比較。

観点 SNS Twilio
統合 AWS ネイティブ スタンドアロン
SMS コスト `0.0075/メッセージ `0.01/メッセージ
プログラマティック API シンプル リッチ(会話フロー等)
推奨用途 OTP・トランザクション 会話型 SMS・チャット

6. SNS vs SendGrid・Mailgun(Email 比較)

Email 配信での比較。

観点 SNS Email SendGrid
統合 AWS ネイティブ スタンドアロン
Template 管理 基本的 リッチ
配信分析 基本 詳細
推奨用途 トランザクション Email マーケティング Email

7. SNS vs Firebase Cloud Messaging(Mobile Push 比較)

モバイルプッシュ統合での比較。

観点 SNS Firebase Cloud Messaging
統合 AWS ネイティブ Google エコシステム
SDK 複雑さ シンプル FCM SDK 必須
デバイス数 無制限 無制限
推奨用途 AWS ユーザー Google Cloud ユーザー

8. SNS vs Pusher(外部比較:リアルタイム)

リアルタイム配信での比較。

観点 SNS Pusher
用途 サーバー間 クライアント間リアルタイム通信
WebSocket 非対応 対応
推奨用途 バックエンド統合 リアルタイムアプリ

比較マトリクス一覧

優先事項 推奨ツール 理由
最小セットアップ SNS フルマネージド
コスト最小化 SNS 従量課金
複雑なルーティング EventBridge パターンマッチング豊富
高スループット Kinesis シャード制御
モバイル通知専門 Firebase Push エコシステム統合
Email 専門 SendGrid マーケティング機能
SMS 専門 Twilio 会話フロー
セルフホスト Kafka 完全制御

クライアントとエコシステム

初心者向けメモ: SNS は UI・CLI・SDK・IaC 多様なツールで操作可能。自動化・統合を進めるには、これらの組み合わせ理解が必須です。

1. AWS CLI

# トピック作成
aws sns create-topic \
  --name orders \
  --region us-east-1

# メッセージ発行
aws sns publish \
  --topic-arn arn:aws:sns:us-east-1:123456789012:orders \
  --message 'Order created' \
  --message-attributes \
    "type={DataType=String,StringValue=order}" \
    "status={DataType=String,StringValue=created}"

# サブスクリプション作成
aws sns subscribe \
  --topic-arn arn:aws:sns:us-east-1:123456789012:orders \
  --protocol sqs \
  --notification-endpoint arn:aws:sqs:us-east-1:123456789012:orders-queue

# リスト取得
aws sns list-topics
aws sns list-subscriptions

2. AWS SDK(複数言語)

Python(boto3 v3)

import boto3

sns = boto3.client('sns')

# トピック作成
topic = sns.create_topic(Name='orders')
topic_arn = topic['TopicArn']

# メッセージ発行
response = sns.publish(
    TopicArn=topic_arn,
    Message='Order: ORD-12345 created',
    Subject='New Order',
    MessageAttributes={
        'type': {'DataType': 'String', 'StringValue': 'order'},
        'status': {'DataType': 'String', 'StringValue': 'created'},
        'amount': {'DataType': 'Number', 'StringValue': '1500'}
    }
)

print(f'Message ID: {response["MessageId"]}')

JavaScript(AWS SDK v3)

import { SNSClient, PublishCommand } from "@aws-sdk/client-sns";

const sns = new SNSClient({ region: "us-east-1" });

const publish = async () => {
  const result = await sns.send(new PublishCommand({
    TopicArn: "arn:aws:sns:us-east-1:123456789012:orders",
    Message: "Order created",
    MessageAttributes: {
      "type": { DataType: "String", StringValue: "order" },
      "status": { DataType: "String", StringValue: "created" }
    }
  }));
  
  console.log(`Message sent: ${result.MessageId}`);
};

publish();

Go

package main

import (
	"context"
	"fmt"

	"github.com/aws/aws-sdk-go-v2/aws"
	"github.com/aws/aws-sdk-go-v2/config"
	"github.com/aws/aws-sdk-go-v2/service/sns"
	"github.com/aws/aws-sdk-go-v2/service/sns/types"
)

func main() {
	cfg, _ := config.LoadDefaultConfig(context.TODO())
	client := sns.NewFromConfig(cfg)

	result, _ := client.Publish(context.TODO(), &sns.PublishInput{
		TopicArn: aws.String("arn:aws:sns:us-east-1:123456789012:orders"),
		Message:  aws.String("Order created"),
		MessageAttributes: map[string]types.MessageAttributeValue{
			"type": {
				DataType:    aws.String("String"),
				StringValue: aws.String("order"),
			},
		},
	})

	fmt.Printf("Message ID: %v\n", result.MessageId)
}

3. Infrastructure as Code(IaC)

CloudFormation

Resources:
  OrderTopic:
    Type: AWS::SNS::Topic
    Properties:
      TopicName: orders
      KmsMasterKeyId: !Ref EncryptionKey

  OrderQueue:
    Type: AWS::SQS::Queue
    Properties:
      QueueName: order-queue

  OrderSubscription:
    Type: AWS::SNS::Subscription
    Properties:
      TopicArn: !Ref OrderTopic
      Protocol: sqs
      Endpoint: !GetAtt OrderQueue.Arn
      FilterPolicy:
        type:
          - order
        status:
          - created

Terraform

provider "aws" {
  region = "us-east-1"
}

resource "aws_sns_topic" "orders" {
  name = "orders"
  kms_master_key_id = aws_kms_key.sns.id
}

resource "aws_sqs_queue" "order_queue" {
  name = "order-queue"
}

resource "aws_sns_topic_subscription" "orders_to_queue" {
  topic_arn = aws_sns_topic.orders.arn
  protocol  = "sqs"
  endpoint  = aws_sqs_queue.order_queue.arn
  
  filter_policy = jsonencode({
    type = ["order"]
    status = ["created"]
  })
}

output "topic_arn" {
  value = aws_sns_topic.orders.arn
}

CDK(TypeScript)

import * as cdk from 'aws-cdk-lib';
import * as sns from 'aws-cdk-lib/aws-sns';
import * as sqs from 'aws-cdk-lib/aws-sqs';
import * as subscriptions from 'aws-cdk-lib/aws-sns-subscriptions';

export class SNSStack extends cdk.Stack {
  constructor(scope: cdk.App, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    const topic = new sns.Topic(this, 'OrderTopic', {
      displayName: 'Orders',
      fifo: false,
    });

    const queue = new sqs.Queue(this, 'OrderQueue', {
      queueName: 'order-queue',
    });

    topic.addSubscription(
      new subscriptions.SqsSubscription(queue, {
        filterPolicy: {
          type: sns.SubscriptionFilter.stringFilter({
            allowlist: ['order'],
          }),
          status: sns.SubscriptionFilter.stringFilter({
            allowlist: ['created'],
          }),
        },
      })
    );
  }
}

4. サーバーレス Framework

# serverless.yml
service: order-service

functions:
  orderCreated:
    handler: handlers.orderCreated
    events:
      - sns:
          arn: arn:aws:sns:us-east-1:123456789012:orders
          topicName: orders
          filterPolicy:
            type:
              - order
            status:
              - created

resources:
  Resources:
    OrderTopic:
      Type: AWS::SNS::Topic
      Properties:
        TopicName: orders

5. EventBridge Rule(SNS トリガー)

EventRule:
  Type: AWS::Events::Rule
  Properties:
    EventPattern:
      source:
        - aws.ec2
      detail-type:
        - EC2 Instance Launch
    State: ENABLED
    Targets:
      - Arn: !Ref SNSTopic
        RoleArn: !GetAtt EventBridgeRole.Arn
        Id: SNSTarget

6. Lambda Layer(SNS ヘルパー)

# lambda_layer/sns_helper.py
import boto3

class SNSHelper:
    def __init__(self):
        self.sns = boto3.client('sns')
    
    def publish_message(self, topic_arn, message, attributes=None):
        return self.sns.publish(
            TopicArn=topic_arn,
            Message=message,
            MessageAttributes=attributes or {}
        )
    
    def create_subscription(self, topic_arn, protocol, endpoint):
        return self.sns.subscribe(
            TopicArn=topic_arn,
            Protocol=protocol,
            Endpoint=endpoint
        )

7. CI/CD 統合

GitHub Actions

name: Deploy SNS

on: [push]

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - uses: actions/setup-python@v2
        with:
          python-version: 3.9
      
      - name: Deploy with Terraform
        run: |
          terraform init
          terraform plan
          terraform apply -auto-approve
        env:
          AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
          AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}

ベストプラクティス

1. メッセージ設計

推奨:

  • JSON フォーマットで構造化
  • ペイロードは最小限(大きなデータは S3 参照)
  • メッセージ ID で重複検知

非推奨:

  • プレーンテキスト・バイナリの混在
  • 平文での機密情報
# 良い例
message = {
    "order_id": "ORD-12345",
    "user_id": "USR-67890",
    "amount": 1500.00,
    "status": "created",
    "timestamp": "2026-04-26T10:30:00Z"
}

# 悪い例
message = "Order ORD-12345 for user USR-67890 with amount 1500"

2. エラー処理・リトライ戦略

推奨:

  • DLQ で配信失敗メッセージを追跡
  • exponential backoff による再試行
  • 冪等な処理設計(重複配信対応)
def process_message(message):
    # Idempotent processing
    message_id = message['MessageId']
    
    # DB で既処理チェック
    if is_already_processed(message_id):
        return  # Skip if already processed
    
    try:
        # Main processing
        handle_order(message)
        mark_as_processed(message_id)
    except Exception as e:
        # Retry logic handled by SQS/Lambda
        raise

3. セキュリティ

必須:

  • IAM による最小権限制御
  • KMS 暗号化(機密データ)
  • VPC Endpoint(プライベートネットワーク)
  • HTTPS/TLS 強制
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Deny",
      "Principal": "*",
      "Action": "sns:*",
      "Resource": "*",
      "Condition": {
        "Bool": {
          "aws:SecureTransport": "false"
        }
      }
    }
  ]
}

4. スケーラビリティ

推奨:

  • Auto Scaling Lambda・SQS ワーカー
  • Metric-based alerting
  • スループット分析(CloudWatch)

非推奨:

  • 固定プロビジョニング
  • 手動スケーリング

5. 観測性・モニタリング

推奨:

  • CloudWatch メトリクス監視
  • DLQ メッセージ数アラーム
  • X-Ray による分散トレーシング
SNSMetricsAlarm:
  Type: AWS::CloudWatch::Alarm
  Properties:
    MetricName: NumberOfNotificationsFailed
    Namespace: AWS/SNS
    Statistic: Sum
    Period: 300
    Threshold: 10
    ComparisonOperator: GreaterThanThreshold
    AlarmActions:
      - !Ref AlertTopic

6. コスト最適化

推奨:

  • Standard トピック(FIFO が不要なら)
  • メッセージバッチング
  • 不要なサブスクリプション削除

非推奨:

  • 大量のテスト発行
  • 使用していないトピック放置

7. 運用

推奨:

  • Infrastructure as Code(Terraform・CloudFormation)
  • ダッシュボード・ドキュメント整備
  • 定期的な災害復旧テスト

トラブルシューティング

問題 1:メッセージが SQS キューに到達しない

原因チェックリスト:

  1. ✅ SNS-SQS ポリシーが正しいか確認
{
  "Effect": "Allow",
  "Principal": {
    "Service": "sns.amazonaws.com"
  },
  "Action": "sqs:SendMessage",
  "Resource": "arn:aws:sqs:region:account:queue-name",
  "Condition": {
    "ArnEquals": {
      "aws:SourceArn": "arn:aws:sns:region:account:topic-name"
    }
  }
}
  1. ✅ フィルタリングポリシーが正しいか
aws sns get-subscription-attributes \
  --subscription-arn arn:aws:sns:region:account:topic:subscription-id \
  --attribute-name FilterPolicy
  1. ✅ SQS キューが存在・アクセス可能か
aws sqs get-queue-attributes \
  --queue-url https://sqs.region.amazonaws.com/account/queue-name \
  --attribute-names All

問題 2:SMS・Email が送信されない

原因チェックリスト:

  1. ✅ SMS・Email サブスクリプション確認メール(Confirmation)が承認されているか
aws sns list-subscriptions \
  --query 'Subscriptions[?SubscriptionArn != "PendingConfirmation"]'
  1. ✅ SMS 送信制限に達していないか(AWS Support に申請)

  2. ✅ Email スパムフォルダを確認

問題 3:Lambda が SNS イベントを受け取らない

原因チェックリスト:

  1. ✅ Lambda 実行ロール に SNS invoke 権限があるか
{
  "Effect": "Allow",
  "Action": "sns:*",
  "Resource": "*"
}
  1. ✅ Lambda ログ(CloudWatch Logs)でエラーを確認
aws logs tail /aws/lambda/function-name --follow
  1. ✅ Lambda タイムアウト設定を確認

問題 4:メッセージ重複が発生

原因と対応:

  • Standard トピック使用:重複は正常。Consumer 側で冪等性を確保
  • FIFO トピック使用:Deduplication ID が正しいか確認
sns.publish(
    TopicArn=topic_arn,
    Message='Order 123',
    MessageDeduplicationId='ORD-12345',  # 重複排除キー
    MessageGroupId='orders'  # グループ ID
)

2025-2026 最新動向

1. Message Data Protection(MDP)

2025 年に導入予定の機能。メッセージ本体をフィルタリング・マスキング。

MessageDataProtectionPolicy:
  - Action: Encrypt
    Scope: ALL
  - Action: Mask
    Scope: PII_FIELDS
    MaskCharacter: '*'

2. Archive and Replay(プレビュー)

メッセージをアーカイブして、後から再配信・リプレイ。

SNS Topic
  ├→ Current Subscriptions(即座配信)
  └→ Archive(S3 保存)
       └→ Replay(後で再配信)

3. Token Authentication(OIDC)

IAM に依存しない、OIDC ベース認証。

  • 従来: IAM User/Role + Access Key
  • 新規: OIDC Token(Google・GitHub 等)

4. Cost Optimizations

  • Batch API:複数メッセージを 1 回の呼び出しで発行
  • Regional Burst:リージョン間低遅延送信

5. Mobile Push 強化

  • Web Push Protocol(W3C)対応予定
  • Rich notification(リッチメディア対応)

6. FIFO 拡張

  • メッセージグループ化の範囲拡大
  • 重複排除の時間窓制御

学習リソース

公式ドキュメント

チュートリアル

コミュニティリソース

  • AWS ブログ記事
  • Stack Overflow(amazon-sns タグ)
  • GitHub ベストプラクティス例

実装例・活用シーン

シーン 1:E-commerce 注文処理

graph TD
    OrderAPI["Order API"]
    SNS["SNS: order-created"]
    
    QueueInventory["SQS: inventory-queue"]
    InventoryLambda["Lambda: Update Inventory"]
    
    QueueShip["SQS: shipping-queue"]
    ShipLambda["Lambda: Create Shipment"]
    
    QueueEmail["SQS: email-queue"]
    EmailLambda["Lambda: Send Confirmation"]
    
    Analytics["Firehose → S3"]
    
    OrderAPI -->|Publish| SNS
    SNS -->|Fan-out| QueueInventory
    SNS -->|Fan-out| QueueShip
    SNS -->|Fan-out| QueueEmail
    SNS -->|Stream| Analytics
    
    QueueInventory --> InventoryLambda
    QueueShip --> ShipLambda
    QueueEmail --> EmailLambda

シーン 2:インフラアラート統合

graph TD
    CloudWatch["CloudWatch Alarm<br/>CPU > 80%"]
    SNS["SNS: infrastructure-alerts"]
    
    PagerDuty["PagerDuty<br/>HTTP Endpoint"]
    Slack["Lambda → Slack"]
    Email["Email: Admin"]
    SMS["SMS: On-call"]
    
    CloudWatch -->|Trigger| SNS
    SNS -->|Route| PagerDuty
    SNS -->|Route| Slack
    SNS -->|Route| Email
    SNS -->|Route| SMS

導入ロードマップ

フェーズ 期間 タスク
1. Prototype 1-2 週 SNS トピック作成・CLI で動作確認
2. Development 2-4 週 SDK 統合・フィルタリングテスト
3. Staging 1-2 週 本番ライク環境でのテスト
4. Production 継続 リリース・監視・最適化

実装チェックリスト

  • [ ] SNS トピック作成(Standard or FIFO?)
  • [ ] Subscription 設定(プロトコル・エンドポイント)
  • [ ] フィルタリングポリシー定義
  • [ ] IAM ロール・ポリシー作成
  • [ ] KMS 暗号化設定(必要に応じて)
  • [ ] VPC Endpoint 設定(プライベート接続の場合)
  • [ ] CloudWatch メトリクス・アラーム設定
  • [ ] DLQ 設定
  • [ ] Lambda/SQS ハンドラ冪等性確認
  • [ ] 本番テスト実施
  • [ ] ドキュメント整備
  • [ ] チーム向け運用ガイド作成

まとめ

Amazon SNS は 「1 対多のメッセージング・通知・イベント駆動アーキテクチャの中核サービス」。Fan-out パターンでマイクロサービス間の疎結合を実現し、複数の配信プロトコル(SQS・Lambda・HTTP・Email・SMS・モバイルプッシュ)をネイティブサポート。

主要ユースケース:

  • イベント駆動アーキテクチャ(Fan-out)
  • CloudWatch アラーム複数チャネル配信
  • モバイルプッシュ通知統一管理
  • SMS・Email トランザクション通知
  • データアーカイブ(Firehose 経由)

他ツールとの選定軸:

  • シンプルな Fan-out: SNS ✅
  • 複雑なルーティング: EventBridge
  • メッセージキューイング: SQS
  • リアルタイムストリーム: Kinesis

セキュリティ・運用のポイント:

  • IAM 最小権限 + KMS 暗号化
  • VPC Endpoint によるプライベート接続
  • DLQ・CloudWatch アラーム監視
  • Infrastructure as Code(Terraform)管理

本ドキュメントを通じて、SNS の概念・設計・実装・運用を包括的に理解できます。自社のアーキテクチャに応じ、Fan-out・FIFO・フィルタリング等の機能を組み合わせて、信頼性高く拡張可能なシステムを構築してください。


参考文献

AWS 公式ドキュメント

  1. Amazon SNS Developer Guide
  2. SNS API Reference
  3. SNS Pricing
  4. SNS Best Practices
  5. SNS Message Filtering
  6. SNS Mobile Push Notifications
  7. SNS FIFO Topics
  8. SNS-SQS Fan-out Pattern
  9. SNS with AWS Lambda
  10. SNS with Kinesis Data Firehose

関連サービスドキュメント

モバイルプッシュ・メッセージング標準

イベント駆動設計

参考資料


最終更新: 2026-04-26 バージョン: 2.1(2026年Q2更新版) 参考文献: 16+件