Amazon Simple Notification Service(SNS)を本番運用するうえでの設計・セキュリティ・信頼性・コスト・運用の指針をまとめたものです。
目次
- 基本概念の整理
- アーキテクチャ設計
- セキュリティ
- 信頼性・耐障害性
- 監視・可観測性
- コスト最適化
- 用途別のポイント
- 運用・ガバナンス
- SNS と他サービスの使い分け
- チェックリスト
1. 基本概念の整理
| 用語 | 説明 |
|---|
| トピック | メッセージの発行先。Publisher はトピックに送信し、Subscriber がトピックを購読する |
| サブスクリプション | トピックと配信先(SQS / Lambda / HTTP(S) / Email / SMS / Firehose / モバイルプッシュ等)の紐付け |
| Standard トピック | 高スループット・少なくとも1回配信(at-least-once)・順序保証なし |
| FIFO トピック | 順序保証・重複排除あり。サブスクライバーは主に SQS(FIFO / Standard) |
| A2A / A2P | アプリ間(Application-to-Application)/人への通知(Application-to-Person) |
2. アーキテクチャ設計
2.1 SNS + SQS のファンアウトを基本形にする
- SNS から直接 Lambda や HTTP へ配信するより、SNS → SQS → コンシューマー の構成を基本とする。
- SQS がバッファとなり、コンシューマー側の障害・スロットリング・デプロイ中でもメッセージを失わない。
- 再試行・可視性タイムアウト・DLQ をコンシューマー単位で制御できる。
- サービスごとに専用 SQS キューを用意し、サブスクライバー同士を疎結合に保つ。
2.2 トピックの粒度
- トピックは「イベントの種類(ドメインイベント)」単位で設計する(例:
order-created, order-cancelled)。
- 1トピックに多種類のイベントを詰め込み、受信側で全件フィルタする設計は避ける。逆に細かく分けすぎて管理不能になるのも避ける。
- 迷う場合は「ドメイン単位のトピック + メッセージ属性によるフィルタリング」が扱いやすい。
2.3 メッセージフィルタリングを活用する
- サブスクリプションフィルターポリシーで、必要なメッセージだけを各サブスクライバーへ配信する。
- 不要な配信が減り、コンシューマーのコストと処理量を削減できる。
- フィルタ対象は
MessageAttributes(デフォルト)または MessageBody(ペイロードベース)を選択可能。
- 属性ベース: 発行側で属性を明示するため契約が明確。
- ペイロードベース: 既存メッセージ構造のまま柔軟にフィルタ可能。
- フィルターポリシーは IaC で管理し、変更時は反映に時間がかかる(最終的整合)ことを考慮する。
2.4 Standard と FIFO の選択
- Standard を基本とし、順序性・厳密な重複排除が業務要件として必要な場合のみ FIFO を選ぶ。
- FIFO を使う場合:
MessageGroupId を適切に分散させ、グループ単位での並列性を確保する(単一グループに集中させない)。
- 重複排除は
MessageDeduplicationId またはコンテンツベース重複排除で行う(重複排除ウィンドウは5分)。
- サブスクライバーの制約やスループット上限を事前に確認する。
2.5 冪等性を前提にする
- Standard トピックは 少なくとも1回配信のため、重複配信が起こりうる。
- コンシューマーは冪等に実装する(イベントIDによる処理済みチェック、条件付き書き込みなど)。
- 順序保証がない前提で、イベントにバージョンやタイムスタンプを持たせて古いイベントを無視できるようにする。
2.6 メッセージサイズ
- 最大ペイロードサイズを超える大きなデータは、S3 に格納して参照(ポインタ)を送る(Claim Check パターン)。
- Java / Python 向けの Extended Client Library を利用可能。
- メッセージは自己完結した最小限のイベント情報にとどめ、詳細は必要に応じて参照させる。
2.7 Raw Message Delivery
- SQS / HTTP / Firehose へ配信する際は、必要に応じて Raw Message Delivery を有効にし、SNS のエンベロープ(JSON ラップ)を除去する。
- コンシューマーのパース処理が簡素化され、ペイロードサイズも削減できる。
- ただし SNS のメタデータ(MessageId, Timestamp 等)が必要な場合は無効のままにする。
3. セキュリティ
3.1 アクセス制御(最小権限)
- IAM ポリシーで
sns:Publish / sns:Subscribe 等を必要なプリンシパル・トピックに限定する。
- トピックポリシー(リソースベースポリシー)で、ワイルドカードプリンシパル(
"Principal": "*")を許可しない。
- やむを得ず許可する場合は
aws:SourceArn / aws:SourceAccount / aws:PrincipalOrgID などの条件キーで絞る。
- S3 や CloudWatch などの AWS サービスからの発行を許可する場合は、Confused Deputy 対策として
aws:SourceArn と aws:SourceAccount を条件に含める。
- クロスアカウント連携は、トピックポリシーと受信側(SQS キューポリシー等)の両方を正しく設定する。
3.2 暗号化
- 保管時の暗号化(SSE)を有効化し、KMS キーで暗号化する。
- 監査や鍵管理の要件がある場合はカスタマー管理キー(CMK) を使用する。
- CMK 使用時は、発行元サービス(S3 / CloudWatch 等)や配信先(暗号化 SQS)に必要な
kms:GenerateDataKey / kms:Decrypt 権限を付与する。
- 転送時の暗号化を強制する: トピックポリシーで
aws:SecureTransport が false のリクエストを Deny する。
- HTTP エンドポイントではなく HTTPS エンドポイントを使用する。
3.3 ネットワーク
- VPC 内から発行する場合は、VPC インターフェイスエンドポイント(PrivateLink) を利用し、インターネットを経由しない。
- エンドポイントポリシーで、利用可能なトピック・アクションを制限する。
3.4 HTTP(S) サブスクライバーの検証
- 受信側で SNS メッセージの署名を検証する(署名証明書の URL が正規の SNS ドメインであることも確認)。
- 署名バージョンは SignatureVersion 2(SHA256) を使用する。
- サブスクリプション確認(SubscriptionConfirmation)は自動承認せず、想定したトピックARNか確認してから承認する。
- 購読解除リンクの悪用を防ぐため、必要に応じてサブスクリプション解除に認証を要求する設定を行う。
3.5 機密データの保護
- メッセージに個人情報・クレデンシャルを含めない設計を優先する。
- 含める必要がある場合は Message Data Protection(データ保護ポリシー) で検出・マスキング・拒否・監査を行う。
4. 信頼性・耐障害性
4.1 配信リトライポリシー
- プロトコルごとに配信リトライの挙動が異なることを理解する。
- AWS マネージドエンドポイント(SQS / Lambda 等)は SNS 側で多数回リトライされる。
- HTTP(S) エンドポイントはリトライポリシー(回数・バックオフ・スロットリング)をカスタマイズ可能。
- HTTP(S) では受信側の処理能力に合わせて 最大受信レートやバックオフを設定する。
4.2 デッドレターキュー(DLQ)
- 各サブスクリプションに SQS の DLQ(Redrive Policy)を設定し、リトライ枯渇メッセージを失わない。
- FIFO トピックのサブスクリプションには FIFO キューの DLQ を使用する。
- DLQ の SQS キューポリシーで SNS からの送信を許可する(暗号化時は KMS 権限も)。
- DLQ のメッセージ数に CloudWatch アラームを設定し、検知・再処理の手順(Runbook)を用意する。
- 配信先が SQS の場合、SQS 側にも DLQ(maxReceiveCount)を設定し、コンシューマーの処理失敗にも備える。
4.3 メッセージアーカイブとリプレイ
- FIFO トピックではメッセージアーカイブとリプレイ機能を利用でき、障害復旧や新規サブスクライバーへの再送に活用できる。
- Standard トピックで長期保存や再処理が必要な場合は、Firehose サブスクリプション経由で S3 にアーカイブする。
4.4 発行側の信頼性
- 発行(Publish)失敗時に備え、SDK のリトライ(指数バックオフ+ジッター)を有効にする。
- DB 更新とイベント発行の整合性が必要な場合は、Transactional Outbox パターン等を検討する。
- 大量発行時は PublishBatch API を使い、API 呼び出し回数とレイテンシを削減する。
4.5 クォータとスロットリング
- リージョン・アカウント単位の Publish TPS、サブスクリプション数、フィルターポリシー数などのサービスクォータを事前に確認する。
- 必要に応じて Service Quotas から上限緩和を申請する。
- 負荷試験でスロットリング(
ThrottledException)発生時の挙動を確認する。
4.6 マルチリージョン
- SNS はリージョナルサービスのため、DR 要件がある場合は複数リージョンにトピックを用意し、発行側でフェイルオーバーできるようにする。
- クロスリージョンでのサブスクライブ(SNS → 別リージョンの SQS 等)も可能だが、レイテンシとリージョン障害時の影響を考慮する。
5. 監視・可観測性
5.1 主要な CloudWatch メトリクス
| メトリクス | 監視の観点 |
|---|
NumberOfMessagesPublished | 発行量の推移・急増/急減の検知 |
NumberOfNotificationsDelivered | 正常配信数 |
NumberOfNotificationsFailed | 配信失敗数(アラーム必須) |
NumberOfNotificationsFilteredOut | フィルタで除外された数(フィルタ設定ミスの検知) |
NumberOfNotificationsRedrivenToDlq | DLQ へ移動した数 |
NumberOfNotificationsFailedToRedriveToDlq | DLQ への移動失敗(権限設定ミス等) |
PublishSize | メッセージサイズの傾向 |
SMSMonthToDateSpentUSD | SMS 利用時のコスト監視 |
5.2 配信ステータスログ
- Lambda / SQS / HTTP(S) / Firehose / アプリ(モバイルプッシュ)等の配信ステータスログを CloudWatch Logs に出力し、失敗原因を追跡可能にする。
- 成功ログのサンプリング率を調整してログ量とコストを抑える。
5.3 トレーシングと監査
- AWS X-Ray のアクティブトレースを有効化し、Publisher → SNS → Subscriber のエンドツーエンドの流れを可視化する。
- CloudTrail で SNS の管理 API(トピック作成・ポリシー変更・サブスクリプション追加等)を記録・監査する。
- AWS Config ルールで、暗号化未設定トピックや過度に公開されたトピックを検出する。
- メッセージに相関ID(correlation ID)を含め、システム横断でのトラブルシュートを容易にする。
6. コスト最適化
- フィルターポリシーで不要な配信を減らし、配信料金とコンシューマー側コストを削減する。
- PublishBatch で API リクエスト数を削減する。
- ペイロードが大きくなる場合はサイズ単位の課金を意識し、S3 参照方式を検討する。
- 不要なトピック・サブスクリプション(特に確認待ちのまま放置されたもの)を定期的に棚卸しする。
- SMS 利用時は月間支出上限(spend limit) を設定し、送信先国・メッセージタイプ(Transactional / Promotional)を適切に選ぶ。
- 配信ステータスログの成功サンプリング率を下げ、ログ費用を抑える。
7. 用途別のポイント
7.1 SMS(A2P)
- 国・地域ごとの規制や送信元 ID(ショートコード、10DLC、トールフリー番号、Sender ID 等)の要件を確認し、事前に登録・申請を行う。
- 重要通知は Transactional、マーケティングは Promotional を使い分ける。
- 新規アカウントは SMS サンドボックス状態のため、本番利用前にサンドボックス解除を申請する。
- オプトアウト(配信停止)の管理を行い、オプトアウト済み番号へ送信しない。
- 大規模・高度な SMS 要件では AWS End User Messaging の利用も検討する。
7.2 Email
- SNS の Email 配信は運用通知・アラート向け。マーケティングやトランザクションメールには Amazon SES を使用する。
- 配信先メールアドレスの購読確認が必要な点に留意する。
7.3 モバイルプッシュ
- プラットフォームアプリケーション(APNs / FCM 等)の認証情報の有効期限・ローテーションを管理する(トークンベース認証の推奨など)。
- 無効化されたエンドポイントを定期的に検出・削除する。
7.4 Lambda サブスクライバー
- Lambda への直接配信は非同期呼び出しとなるため、Lambda 側の非同期呼び出し設定(リトライ回数・失敗時の送信先) も合わせて設定する。
- 同時実行数の制限によるスロットリングを考慮し、高負荷時は SNS → SQS → Lambda 構成を検討する。
8. 運用・ガバナンス
- トピック・サブスクリプション・ポリシーは IaC(CloudFormation / CDK / Terraform) で管理し、手動変更を避ける。
- 命名規則(例:
<env>-<domain>-<event>)とタグ付け(環境・オーナー・コストセンター)を統一する。
- イベントスキーマをドキュメント化し、バージョニングと後方互換性のルールを定める(フィールド追加は互換、削除・型変更は新バージョン)。
- 開発・ステージング・本番でアカウントまたはトピックを分離する。
- 障害時の Runbook(DLQ 再処理、サブスクリプション再作成、ポリシーロールバック手順)を整備する。
9. SNS と他サービスの使い分け
| 要件 | 推奨サービス |
|---|
| シンプルな高スループットのファンアウト(Pub/Sub) | SNS |
| 1対1のキューイング、バッファリング、ワーカー処理 | SQS |
| 複雑なコンテンツベースルーティング、SaaS 連携、スキーマレジストリ、多数のターゲット種別 | EventBridge |
| 順序付きの大量ストリーム処理・リプレイ | Kinesis Data Streams / MSK |
| マーケティング・トランザクションメール | SES |
SNS と EventBridge は併用も可能。高スループット・低レイテンシのファンアウトは SNS、柔軟なルーティングや外部連携は EventBridge という使い分けが一般的。
10. チェックリスト
設計
セキュリティ
信頼性
監視・運用
参考資料