AWSアカウントでSNSとSQSを連携させるには

大栗です。

先日のAWSアカウントを跨いでSQSのメッセージを送信するパターン集というエントリで、クロスアカウントでSNSとSQSを連携させる事に言及しました。しかし、クロスアカウントの場合は、同一アカウントの場合に比べて設定する項目が多いので手順をまとめてみます。

クロスアカウント連携の概要

やりたいことはAWSアカウントを跨いでSQSのメッセージを送信するパターン集の中の『SQSとSNSを連携する場合』の『送信先を送信元に分ける』となります。

送信元のSNSを配置するアカウントをアカウントA、送信先のSQSを配置するアカウントをアカウントBとして説明します。アカウントIDは、仮にアカウントAは「111111111111」、アカウントBは「222222222222」とします。

クロスアカウントのSNSとSQSを連携する設定の手順概要は、以下のようになります。

sns-sqs-overview

クロスアカウントで連携する手順

1. SNSのトピックを作成する (アカウントA)

送信元アカウントでSNSトピックを作成します。

Management ConsoleのSNSの画面でTopicsを表示します。ここでCreate new topicをクリックします。

AWS_SNS

SNSのトピック名と表示名を記載します。

AWS_SNS

作成するとSNSトピックのARNが表示されます。

AWS_SNS

2. SQSを作成する (アカウントB)

送信先アカウントでSQSのキューを作成します。

Management ConsoleのSQSの画面で新しいキューの作成をクリックします。

SQS_Management_Console

キュー名を記載します。ここでは、他の項目をデフォルト値のままとします。キューメッセージの処理ができなかった時に別のキューへ退避する場合にはデッドレターキューに別のキューを指定して下さい。

SQS_Management_Console

キューが作成されます。

SQS_Management_Console

3. SQSポリシーでSNSのトピックを設定する (アカウントB)

送信先アカウントでキューのSQSキューアクセスポリシーを設定します。

「2. SQSを作成する」で作成したキューを選択して「アクセス許可」タブをクリックします。アクセス許可の追加をクリックします。

SQS_Management_Console

「CrossAccess-TEST-B へのアクセス許可の追加」で以下の内容で設定します。設定は続くので下にある「アクセス許可の追加」はクリックしないで下さい。

項目 内容 備考
効果 許可
プリンシパル 「全員(*)」をチェック アクセス元のアカウントID(111111111111)ではアクセスできません
アクション SendMassage

SQS_Management_Console

条件の追加(オプション)のリンクをクリックして条件を表示して以下の内容を入力します。「条件の追加」をクリックして入力した条件を確定します。

項目 内容 備考
限定条件 None
条件 ArnEquals 特定のSNSトピックを許可する場合
キー aws:SourceArn
arn:aws:sns:ap-northeast-1:111111111111:CrossAccess-TEST 特定のSNSトピックを許可する場合

送信元アカウントにある東京リージョン全てのSNSトピックからのアクセスを許可する場合には、条件を「ArnLike」、値を「arn:aws:sns:ap-northeast-1:111111111111:*」のように設定してください。

SQS_Management_Console

条件を確定したのでアクセス許可の追加をクリックします。

SQS_Management_Console

SQSキューアクセスポリシーが設定されました。これでアカウントAのSNSからメッセージを送信できるようになります。

SQS_Management_Console

4. SNSのサブスクリプションを作成する (アカウントA)

送信元アカウントでSNSサブスクリプションを作成します。

SNSの画面で作成したSNSトピックのARNのリンクをクリックします。

AWS_SNS

Create subscriptionをクリックします。

AWS_SNS

「Create subscription」で以下の内容で設定します。

項目 内容 備考
Protocol Amazon SQS
Endpoint arn:aws:sqs:ap-northeast-1:222222222222:CrossAccess-TEST-B 「2. SQSを作成する」で作成したキューのARN

AWS_SNS

作成したサブスクリプションが「PendingConfirmation」となっています。この状態は自動でSQSに確認用メッセージを送信しています。

AWS_SNS

5. メッセージを取得して、許可用URLにアクセスする (アカウントB)

送信先アカウントでSNSの確認用メッセージを確認します。

Management ConsoleのSQSの画面で「2. SQSを作成する」で作成したキューを選択して 、コンテキストメニューかキュー操作のメッセージの表示/削除をクリックします。

SQS_Management_Console_と_投稿の編集_‹_Developers_IO_—_WordPress_と_AWS_SNS_と_1__SNSのトピックを作成する

メッセージを確認するためにメッセージのポーリングを開始をクリックします。

SQS_Management_Console

確認用メッセージを受信しているので詳細のリンクをクリックします。もし確認用メッセージが来ていない場合は「3. SQSポリシーでSNSのトピックを設定する」の内容を見直して下さい。

SQS_Management_Console

確認メッセージのメッセージ本文は、以下のようなフォーマットになっています。メッセージ内の「SubscribeURL」をメモします。

{
  "Type" : "SubscriptionConfirmation",
  "MessageId" : "a1b2c3d4-a1b2-a1b2-a1b2-a1b2c3d4e5f6",
  "Token" : "a1b2c3d4a1b2c3d4a1b2c3d4a1b2c3d4a1b2c3d4a1b2c3d4a1b2c3d4a1b2c3d4a1b2c3d4a1b2c3d4a1b2c3d4a1b2c3d4a1b2c3d4a1b2c3d4a1b2c3d4a1b2c3d4a1b2c3d4a1b2c3d4a1b2c3d4a1b2c3d4a1b2c3d4a1b2c3d4a1b2c3d4a1b2c3d4a1b2c3d4a1b2c3d4a1b2c3d4a1b2c3d4a1b2c3d4a1b2c3d4a1b2c3d4a1b2c3d4",
  "TopicArn" : "arn:aws:sns:ap-northeast-1:111111111111:CrossAccess-TEST",
  "Message" : "You have chosen to subscribe to the topic arn:aws:sns:ap-northeast-1:111111111111:CrossAccess-TEST.\nTo confirm the subscription, visit the SubscribeURL included in this message.",
  "SubscribeURL" : "https://sns.ap-northeast-1.amazonaws.com/?Action=ConfirmSubscription&TopicArn=arn:aws:sns:ap-northeast-1:111111111111:CrossAccess-TEST&Token=a1b2c3d4a1b2c3d4a1b2c3d4a1b2c3d4a1b2c3d4a1b2c3d4a1b2c3d4a1b2c3d4a1b2c3d4a1b2c3d4a1b2c3d4a1b2c3d4a1b2c3d4a1b2c3d4a1b2c3d4a1b2c3d4a1b2c3d4a1b2c3d4a1b2c3d4a1b2c3d4a1b2c3d4a1b2c3d4a1b2c3d4a1b2c3d4a1b2c3d4a1b2c3d4a1b2c3d4a1b2c3d4a1b2c3d4a1b2c3d4a1b2c3d4a1b2c3d4",
  "Timestamp" : "2017-01-16T05:55:27.995Z",
  "SignatureVersion" : "1",
  "Signature" : "a1b2c3d4a1b2c3d4a1b2c3d4a1b2c3d4a1b2c3d4a1b2c3d4a1b2c3d4a1b2c3d4a1b2c3d4a1b2c3d4a1b2c3d4a1b2c3d4a1b2c3d4a1b2c3d4a1b2c3d4a1b2c3d4a1b2c3d4a1b2c3d4a1b2c3d4a1b2c3d4a1b2c3d4a1b2c3d4a1b2c3d4a1b2c3d4a1b2c3d4a1b2c3d4a1b2c3d4a1b2c3d4a1b2c3d4a1b2c3d4a1b2c3d4a1b2c3d4a1b2c3d4a1b2c3d4a1b2c3d4a1b2c3d4a1b2c3d4a1b2c3d4a1b2c3d4a1b2c3d4a1b2c3d4a1b2c3d4a1b2c3d4",
  "SigningCertURL" : "https://sns.ap-northeast-1.amazonaws.com/SimpleNotificationService-a1b2c3d4a1b2c3d4a1b2c3d4a1b2c3d4.pem"
}

メッセージのSubscribeURLの内容に対してアクセスします。ブラウザからアクセスすると以下のように表示されます。これでSNSからのメッセージの送信許可を行いました。

ConfirmSubscription

SQS内の確認用メッセージは不要になったので、キューから削除しておいてください。

6. SNSのサブスクリプションのステータスを確認する (アカウントA)

送信元アカウントでSNSサブスクリプションのステータスを確認します。

作成したサブスクリプションの表示が「PendingConfirmation」からARNへ変わっています。これでSNS側からも許可されたことを確認できました。

AWS_SNS

SNSからメッセージを送信してみる

SNSからメッセージをパブリッシュする (アカウントA)

作成したSNSトピックを選択してPublish to topicをクリックします。

AWS_SNS

以下のようなメッセージ内容で送信します。

AWS_SNS

SQSでメッセージを読む (アカウントB)

キューに入っているメッセージを確認します。

SQS_Management_Console

以下のような内容になります。"Subject"、"Message"に入力したメッセ0時が入っています。

{
  "Type" : "Notification",
  "MessageId" : "a1b2c3d4-a1b2-a1b2-a1b2-a1b2c3d4e5f6",
  "TopicArn" : "arn:aws:sns:ap-northeast-1:111111111111:CrossAccess-TEST",
  "Subject" : "TEST-Sub",
  "Message" : "TEST-Message 1\nTEST-Message 2\nTEST-Message 3",
  "Timestamp" : "2017-01-16T06:50:34.638Z",
  "SignatureVersion" : "1",
  "Signature" : "a1b2c3d4a1b2c3d4a1b2c3d4a1b2c3d4a1b2c3d4a1b2c3d4a1b2c3d4a1b2c3d4a1b2c3d4a1b2c3d4a1b2c3d4a1b2c3d4a1b2c3d4a1b2c3d4a1b2c3d4a1b2c3d4a1b2c3d4a1b2c3d4a1b2c3d4a1b2c3d4a1b2c3d4a1b2c3d4a1b2c3d4a1b2c3d4a1b2c3d4a1b2c3d4a1b2c3d4a1b2c3d4a1b2c3d4a1b2c3d4a1b2c3d4a1b2c3d4a1b2c3d4a1b2c3d4a1b2c3d4a1b2c3d4a1b2c3d4a1b2c3d4a1b2c3d4a1b2c3d4a1b2c3d4a1b2c3d4a1b2c3d4",
  "SigningCertURL" : "https://sns.ap-northeast-1.amazonaws.com/SimpleNotificationService-a1b2c3d4a1b2c3d4a1b2c3d4a1b2c3d4.pem"
  "UnsubscribeURL" : "https://sns.ap-northeast-1.amazonaws.com/?Action=Unsubscribe&SubscriptionArn=arn:aws:sns:ap-northeast-1:111111111111:CrossAccess-TEST:a1b2c3d4-a1b2-a1b2-a1b2-a1b2c3d4e5f6",
  "MessageAttributes" : {
    "AWS.SNS.MOBILE.MPNS.Type" : {"Type":"String","Value":"token"},
    "AWS.SNS.MOBILE.MPNS.NotificationClass" : {"Type":"String","Value":"realtime"},
    "AWS.SNS.MOBILE.WNS.Type" : {"Type":"String","Value":"wns/badge"}
  }
}

さいごに

同一アカウントの場合はSQSの画面で「SNS トピックへのキューのサブスクライブ」を行うだけでSNSとSQSの連携が可能なのですが、クロスアカウントの場合は、権限が分離されているので送信、受信を行って良いかを確認するステップが追加されています。 クロスアカウントで設定することは多くないと思いますが、この手順が参考になれば幸いです。