sns について
Amazon SNSを使ったPub/Subメッセージング向けのリファレンススキルです。トピックやサブスクリプション、メッセージフィルタリング、CLIとboto3の例、配信時の調査方法を扱います。
主な機能
- 01StandardとFIFOのトピック
- 02複数のサブスクリプションプロトコル
- 03属性ベースのメッセージフィルタリング
- 04AWS CLIとboto3の例
- 05複数のSQSキューへのファンアウト
- 06配信トラブルシューティング
活用シーン
- 01トピックの購読者に通知を発行
- 02サブスクリプションフィルターでメッセージをルーティング
- 03メッセージをSQSキューにファンアウト
- 04購読先に届かないメッセージを調査
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ itsmostafa/ aws-agent-skills --skill snsインストール後、Claude Code で/snsを入力して読み込まれたか確認します。
同梱ファイルnotification-patterns.md
詳細
AWS SNS
Amazon Simple Notification Service(SNS)は、アプリケーション間(A2A)およびアプリケーションとユーザー間(A2P)の通信に対応する、フルマネージド型のパブリッシュ/サブスクライブメッセージングサービスです。
目次
基本概念
トピック
メッセージを発行するための名前付きチャネルです。発行者はトピックに送信し、サブスクライバーはトピックから受信します。
トピックの種類
| 種類 | 説明 | ユースケース |
|---|---|---|
| Standard | 順序はベストエフォート、少なくとも1回配信 | ほとんどのユースケース |
| FIFO | 厳密な順序、正確に1回配信 | 順序が重要な場合 |
サブスクリプションプロトコル
| プロトコル | 説明 |
|---|---|
| Lambda | Lambda 関数を呼び出します |
| SQS | SQS キューに送信します |
| HTTP/HTTPS | エンドポイントに POST します |
| メールを送信します | |
| SMS | テキストメッセージを送信します |
| Application | モバイルプッシュ通知 |
メッセージフィルタリング
メッセージ属性に基づいて、特定のサブスクライバーにメッセージをルーティングします。
一般的なパターン
トピックの作成とサブスクライブ
AWS CLI:
# Create standard topic
aws sns create-topic --name my-topic
# Create FIFO topic
aws sns create-topic \
--name my-topic.fifo \
--attributes FifoTopic=true
# Subscribe Lambda
aws sns subscribe \
--topic-arn arn:aws:sns:us-east-1:123456789012:my-topic \
--protocol lambda \
--notification-endpoint arn:aws:lambda:us-east-1:123456789012:function:my-function
# Subscribe SQS
aws sns subscribe \
--topic-arn arn:aws:sns:us-east-1:123456789012:my-topic \
--protocol sqs \
--notification-endpoint arn:aws:sqs:us-east-1:123456789012:my-queue
# Subscribe email
aws sns subscribe \
--topic-arn arn:aws:sns:us-east-1:123456789012:my-topic \
--protocol email \
--notification-endpoint [email protected]
boto3:
import boto3
sns = boto3.client('sns')
# Create topic
response = sns.create_topic(Name='my-topic')
topic_arn = response['TopicArn']
# Subscribe Lambda
sns.subscribe(
TopicArn=topic_arn,
Protocol='lambda',
Endpoint='arn:aws:lambda:us-east-1:123456789012:function:my-function'
)
# Subscribe SQS with filter
sns.subscribe(
TopicArn=topic_arn,
Protocol='sqs',
Endpoint='arn:aws:sqs:us-east-1:123456789012:order-queue',
Attributes={
'FilterPolicy': '{"event_type": ["order_created", "order_updated"]}'
}
)
メッセージの発行
import boto3
import json
sns = boto3.client('sns')
topic_arn = 'arn:aws:sns:us-east-1:123456789012:my-topic'
# Simple publish
sns.publish(
TopicArn=topic_arn,
Message='Hello, World!',
Subject='Notification'
)
# Publish with attributes (for filtering)
sns.publish(
TopicArn=topic_arn,
Message=json.dumps({'order_id': '12345', 'status': 'created'}),
MessageAttributes={
'event_type': {
'DataType': 'String',
'StringValue': 'order_created'
},
'priority': {
'DataType': 'Number',
'StringValue': '1'
}
}
)
# Publish to FIFO topic
sns.publish(
TopicArn='arn:aws:sns:us-east-1:123456789012:my-topic.fifo',
Message=json.dumps({'order_id': '12345'}),
MessageGroupId='order-12345',
MessageDeduplicationId='unique-id'
)
メッセージフィルタリング
# Add filter policy to subscription
aws sns set-subscription-attributes \
--subscription-arn arn:aws:sns:us-east-1:123456789012:my-topic:abc123 \
--attribute-name FilterPolicy \
--attribute-value '{
"event_type": ["order_created"],
"priority": [{"numeric": [">=", 1]}]
}'
フィルターポリシーの例:
// Exact match
{"event_type": ["order_created", "order_updated"]}
// Prefix match
{"customer_id": [{"prefix": "PREMIUM-"}]}
// Numeric comparison
{"price": [{"numeric": [">=", 100, "<=", 500]}]}
// Exists check
{"customer_id": [{"exists": true}]}
// Anything but
{"event_type": [{"anything-but": ["deleted"]}]}
// Combined
{
"event_type": ["order_created"],
"region": ["us-east", "us-west"],
"priority": [{"numeric": [">=", 1]}]
}
ファンアウトパターン(SNS から複数の SQS へ)
import boto3
import json
sns = boto3.client('sns')
sqs = boto3.client('sqs')
# Create topic
topic = sns.create_topic(Name='orders-topic')
topic_arn = topic['TopicArn']
# Create queues for different processors
queues = {
'analytics': sqs.create_queue(QueueName='order-analytics')['QueueUrl'],
'fulfillment': sqs.create_queue(QueueName='order-fulfillment')['QueueUrl'],
'notification': sqs.create_queue(QueueName='order-notification')['QueueUrl']
}
# Subscribe each queue
for name, queue_url in queues.items():
queue_arn = sqs.get_queue_attributes(
QueueUrl=queue_url,
AttributeNames=['QueueArn']
)['Attributes']['QueueArn']
sns.subscribe(
TopicArn=topic_arn,
Protocol='sqs',
Endpoint=queue_arn
)
# One publish reaches all queues
sns.publish(
TopicArn=topic_arn,
Message=json.dumps({'order_id': '12345', 'total': 99.99})
)
SNS 用の Lambda 権限
aws lambda add-permission \
--function-name my-function \
--statement-id sns-trigger \
--action lambda:InvokeFunction \
--principal sns.amazonaws.com \
--source-arn arn:aws:sns:us-east-1:123456789012:my-topic
CLI リファレンス
トピックの管理
| コマンド | 説明 |
|---|---|
aws sns create-topic | トピックを作成します |
aws sns delete-topic | トピックを削除します |
aws sns list-topics | トピックを一覧表示します |
aws sns get-topic-attributes | トピックの設定を取得します |
aws sns set-topic-attributes | トピックの設定を更新します |
サブスクリプション
| コマンド | 説明 |
|---|---|
aws sns subscribe | サブスクリプションを作成します |
aws sns unsubscribe | サブスクリプションを削除します |
aws sns list-subscriptions | すべてのサブスクリプションを一覧表示します |
aws sns list-subscriptions-by-topic | トピックのサブスクリプションを一覧表示します |
aws sns confirm-subscription | 保留中のサブスクリプションを確認します |
発行
| コマンド | 説明 |
|---|---|
aws sns publish | メッセージを発行します |
ベストプラクティス
信頼性
- 耐久性には SQS を使用します — SNS はプッシュ型で、SQS はメッセージをキューに保持します
- HTTP/HTTPS エンドポイントには再試行を実装します
- 配信に失敗した場合に備えて DLQ を設定します
- 順序が必要な場合は FIFO トピックを使用します
セキュリティ
- トピックポリシーを使用してアクセスを制御します
- SSE による暗号化を有効にします
- プライベートアクセスには VPC エンドポイントを使用します
# Enable SSE
aws sns set-topic-attributes \
--topic-arn arn:aws:sns:us-east-1:123456789012:my-topic \
--attribute-name KmsMasterKeyId \
--attribute-value alias/my-key
コストの最適化
- メッセージフィルタリングを使用して不要な配信を減らします
- 可能な場合は操作をバッチ処理します
- 未使用のトピックやサブスクリプションを監視して削除します
メッセージの設計
- メッセージを小さく保ちます(上限は 256 KB)
- ルーティングにはメッセージ属性を使用します
- トレース用に相関 ID を含めます
トラブルシューティング
サブスクリプションがメッセージを受信しない
確認事項:
- サブスクリプションが確認済みである(保留中ではない)
- フィルターポリシーがメッセージ属性と一致している
- ターゲットの権限(Lambda、SQS)
# Check subscription status
aws sns list-subscriptions-by-topic \
--topic-arn arn:aws:sns:us-east-1:123456789012:my-topic
# Check subscription attributes
aws sns get-subscription-attributes \
--subscription-arn arn:aws:sns:us-east-1:123456789012:my-topic:abc123
HTTP エンドポイントが動作しない
デバッグ:
# Check delivery status logging
aws sns set-topic-attributes \
--topic-arn arn:aws:sns:us-east-1:123456789012:my-topic \
--attribute-name DeliveryPolicy \
--attribute-value '{
"http": {
"defaultHealthyRetryPolicy": {
"minDelayTarget": 20,
"maxDelayTarget": 20,
"numRetries": 3,
"numMaxDelayRetries": 0,
"numNoDelayRetries": 0,
"numMinDelayRetries": 0,
"backoffFunction": "linear"
}
}
}'
メッセージがフィルターに一致しない
確認事項:
- メッセージ属性が設定されている(本文ではない)
- 属性の型が一致している(String と Number)
- フィルターポリシーの構文が正しい
# Correct: attributes must be message attributes
sns.publish(
TopicArn=topic_arn,
Message='body content',
MessageAttributes={
'event_type': {
'DataType': 'String',
'StringValue': 'order_created' # This is filtered
}
}
)
# Wrong: this won't be filtered
sns.publish(
TopicArn=topic_arn,
Message=json.dumps({'event_type': 'order_created'}) # Not filtered
)
SQS が SNS から受信しない
SQS キューポリシーを確認します:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {"Service": "sns.amazonaws.com"},
"Action": "sqs:SendMessage",
"Resource": "arn:aws:sqs:us-east-1:123456789012:my-queue",
"Condition": {
"ArnEquals": {
"aws:SourceArn": "arn:aws:sns:us-east-1:123456789012:my-topic"
}
}
}
]
}
参考資料
コメント
Markdown 対応