目次
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 利用
目次
- 概要
- SNS が解決する課題
- 主な特徴
- アーキテクチャ(Topic・Subscription・Publisher・Subscriber)
- トピックタイプ(Standard・FIFO)
- サブスクリプションプロトコル(SQS・Lambda・HTTP・Email・SMS・Mobile Push・Kinesis)
- 主要ユースケース(10+)
- メッセージフィルタリング
- メッセージアトリビュート
- SMS(Promotional・Transactional・SMS Originating Number)
- Mobile Push(APNs・FCM・ADM)
- SNS-SQS ファンアウトパターン
- SNS + Kinesis Data Firehose(S3 アーカイブ)
- DLQ(Dead Letter Queue)
- セキュリティ(IAM・Resource Policy・KMS・VPC Endpoint)
- CloudWatch メトリクス
- 他の類似ツールとの比較
- クライアントとエコシステム(CLI・SDK・IaC)
- ベストプラクティス
- トラブルシューティング
- 2025-2026 最新動向
- 学習リソース
- 実装例・活用シーン
- 導入ロードマップ
- 実装チェックリスト
- まとめ
- 参考文献
概要
初心者向けメモ: 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(発行元)
PublishMessageAPI でトピックにメッセージを送信- 配信先を意識しない(トピックのみ指定)
- 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 |
| メールアドレス | ベストエフォート | 管理者通知 | |
| 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 ペイロード
設定手順:
- Apple Developer Account で APNs 証明書を生成
- AWS SNS で Platform Application を作成
- 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 キューに到達しない
原因チェックリスト:
- ✅ 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"
}
}
}
- ✅ フィルタリングポリシーが正しいか
aws sns get-subscription-attributes \
--subscription-arn arn:aws:sns:region:account:topic:subscription-id \
--attribute-name FilterPolicy
- ✅ SQS キューが存在・アクセス可能か
aws sqs get-queue-attributes \
--queue-url https://sqs.region.amazonaws.com/account/queue-name \
--attribute-names All
問題 2:SMS・Email が送信されない
原因チェックリスト:
- ✅ SMS・Email サブスクリプション確認メール(Confirmation)が承認されているか
aws sns list-subscriptions \
--query 'Subscriptions[?SubscriptionArn != "PendingConfirmation"]'
-
✅ SMS 送信制限に達していないか(AWS Support に申請)
-
✅ Email スパムフォルダを確認
問題 3:Lambda が SNS イベントを受け取らない
原因チェックリスト:
- ✅ Lambda 実行ロール に SNS invoke 権限があるか
{
"Effect": "Allow",
"Action": "sns:*",
"Resource": "*"
}
- ✅ Lambda ログ(CloudWatch Logs)でエラーを確認
aws logs tail /aws/lambda/function-name --follow
- ✅ 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 公式ドキュメント
- Amazon SNS Developer Guide
- SNS API Reference
- SNS Pricing
- SNS Best Practices
- SNS Message Filtering
- SNS Mobile Push Notifications
- SNS FIFO Topics
- SNS-SQS Fan-out Pattern
- SNS with AWS Lambda
- SNS with Kinesis Data Firehose
関連サービスドキュメント
- Amazon SQS Developer Guide
- AWS Lambda Developer Guide
- Amazon EventBridge
- AWS CloudWatch
- AWS IAM
- AWS KMS
モバイルプッシュ・メッセージング標準
- Firebase Cloud Messaging (FCM) Documentation
- Apple Push Notification Service (APNs) Documentation
- W3C Web Push Protocol Specification
イベント駆動設計
- CNCF CloudEvents Specification
- AsyncAPI Initiative - Event-Driven API Design
- AWS Compute Blog - SNS & Messaging Articles
参考資料
最終更新: 2026-04-26 バージョン: 2.1(2026年Q2更新版) 参考文献: 16+件