SNSとSQSのクロスアカウント設定(KMSで暗号化)
SNSからメッセージをAWSの別アカウントSQSに送ってKMSで暗号化する設定をしたのでやり方を紹介します。
どういうことか分かりやすく図で書くと、以下のようになります。 AWSアカウントA(111111111111)のSNS(simple-sns)から、AWSアカウントB(222222222222)のSQS(simple-sqs)に対してメッセージを送ってKMS(simple-kms)でメッセージを暗号化してSQSで保持するようにします。
手順
- 1. SNSトピックを作成 @AWSアカウントA
- 2. KMSを作成 @AWSアカウントB
- 3. SQSキューを作成 @AWSアカウントB
- 4. SQS側でSNSをサブスクライブするように設定 @AWSアカウントB
- 5. SNSからメッセージの送信テスト @AWSアカウントA
- 6. SQSからメッセージの受信確認 @AWSアカウントB
- 参考
アカウントを跨いだクロスアカウントの設定では、権限設定が複雑になり、各リソース(SNS, SQS, KMS)に対してリソースポリシーを設定する必要があります。各リソースに設定するリソースポリシーの説明も手順と合わせて紹介します。
1. SNSトピックを作成 @AWSアカウントA
{ "Sid": "__console_sub_0", "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::222222222222:root" }, "Action": [ "SNS:Subscribe", "SNS:Receive" ], "Resource": "arn:aws:sns:ap-northeast-1:111111111111:simple-sns" }
2. KMSを作成 @AWSアカウントB
今度は、AWSアカウントBにログインして、SQSでデータ暗号化の時に利用するKMSを作成します。AWS managed keysでも aws/sqs
というエイリアス名でSQSのためのKMSがありますがこれは利用しません。なぜなら、AWS managed keysのリソースポリシーは変更することが出来ないので、SNSがKMSを利用できるように設定できないからです。Customer managed keysを使えば、SNSサービスがSQSのデータを暗号化できるポリシーを設定できます。
- 適当なエイリアス名でCustomer managed keyを作成して、Key policyには以下のstatementを追加しておきます。
- このstatementによって、SNSはSQSのデータ暗号化(ViaService)をするときに限ってKMSの
GenerateDataKey
,Decrypt
アクションを利用できるようになります。
- このstatementによって、SNSはSQSのデータ暗号化(ViaService)をするときに限ってKMSの
{ "Sid": "SnsStatement", "Effect": "Allow", "Principal": { "Service": "sns.amazonaws.com" }, "Action": [ "kms:GenerateDataKey", "kms:Decrypt" ], "Resource": "*", "Condition": { "StringEquals": { "kms:ViaService": "sqs.ap-northeast-1.amazonaws.com" } } }
3. SQSキューを作成 @AWSアカウントB
AWSアカウントAからのメッセージを受け取るSQSを、AWSアカウントBのコンソールから作成します。
- sqsの名前は、simple-sqsとします。
- タイプはスタンダードです。
- この作成時には、Access policyはデフォルトのままにして変更はしません。後で設定します。
- Encryptionでは、先ほど作成した Customer managed key の エイリアスを指定します。
4. SQS側でSNSをサブスクライブするように設定 @AWSアカウントB
AWSアカウントBのコンソールから、SNSをサブスクライブするようにSQSを設定します。
{ "Sid": "topic-subscription-arn:aws:sns:ap-northeast-1:111111111111:simple-sns", "Effect": "Allow", "Principal": { "AWS": "*" }, "Action": "SQS:SendMessage", "Resource": "arn:aws:sqs:ap-northeast-1:222222222222:simple-sqs", "Condition": { "ArnLike": { "aws:SourceArn": "arn:aws:sns:ap-northeast-1:111111111111:simple-sns" } } }
5. SNSからメッセージの送信テスト @AWSアカウントA
- SNSから適当にテストメッセージを作成して送信します。
6. SQSからメッセージの受信確認 @AWSアカウントB
- SQSからPoll for messagesを実行してアカウントAのSNSからメッセージが届いていることを確認します。
正直、各サービスのリソースポリシーにはどんな権限を付与すれば良いのか混乱すると思います。落ち着いてポリシーをよく見ながら設定してみてください。