SNSトピックサブスクライブ方法によるSQSキューアクセスポリシーの違い

2022.01.09

いわさです。

Amazon SQSを使って、Amazon SNSをサブスクライブすることが可能です。
ファンアウト構成を取る場合や、あるいはSNSのFIFOトピックを使う場合にSQSと連携すると思います。

私は普段SNSはEメール通知に使うことが多くて気づかなかったのですが、マネジメントコンソールでSQSのSNSサブスクリプションを作成する方法は2つあって、しかもそれぞれで挙動(設定内容)が異なるんですね。

確認してみたことをまとめます。

サブスクリプションの作成

ここではそれぞれの方法で以下2つのサブスクリプションを作成します。

SNSコンソールからサブスクリプションを作成する場合

プロトコルにAmazon SQSを指定し、SQSキューのARNを指定します。

SQSコンソールからサブスクリプションを作成する場合

SQSコンソールの場合は、SNSサブスクリプションタブからサブスクライブ操作を行います。
こちらは登録時にSNSトピックのARNを指定します。

サブスクライブ後のメッセージ送信

2つの方法でSQSキューサブスクリプションを作成したので、メッセージ発行を行ってみましょう。

この時点だと、SQSコンソールから作成したキューへしかメッセージが送信されていません。

エラーメッセージを確認

SNSトピックでログを有効化している場合はCloudWatch Logsで送信エラーの詳細を確認することができるので確認してみましょう。

{
    "notification": {
        "messageMD5Sum": "a21075a36eeddd084e17611a238c7101",
        "messageId": "150563ae-7ce9-5b38-a241-39fd87a9e9cc",
        "topicArn": "arn:aws:sns:ap-northeast-1:123456789012:hoge-sns",
        "timestamp": "2022-01-08 20:50:08.296"
    },
    "delivery": {
        "deliveryId": "6f92685d-ea8f-5353-ac89-320e11cfc7d3",
        "destination": "arn:aws:sqs:ap-northeast-1:123456789012:hoge-sqs",
        "providerResponse": "{\"ErrorCode\":\"AccessDenied\",\"ErrorMessage\":\"Access to the resource https://sqs.ap-northeast-1.amazonaws.com/123456789012/hoge-sqs is denied.\",\"sqsRequestId\":\"Unrecoverable\"}",
        "dwellTimeMs": 61,
        "attempts": 1,
        "statusCode": 403
    },
    "status": "FAILURE"
}

SNSコンソールから作成したサブスクリプションの場合、アクセス権限がないとエラーメッセージが表示されています。

SQSキューにはアクセスポリシーの概念があり、キューへメッセージを送信するためには、送信元にアクセス許可を行う必要があります。

アクセスポリシーの設定が必要ということがわかりましたが、SQSコンソールから作成したサブスクリプションの場合はなぜアクセスできるのでしょうか。

SQSコンソール操作時のCloudTrailを確認してみると、サブスクライブ操作とあわせてアクセスポリシーの設定も行われていました。

SNSコンソールからサブスクライブした場合はSQS側のアクセスポリシーの設定が別途必要。
SQSコンソールからサブスクライブした場合は自動でアクセスポリシー設定がされるということですね。

アクセス件を付与する

SNSコンソールから先程サブスクライブしたSQSキューのアクセスポリシー設定を行ってみましょう。
マネジメントコンソールあるいはAWS CLIから設定が可能です。

aws sqs set-queue-attributes \
--queue-url https://sqs.ap-northeast-1.amazonaws.com/123456789012/hoge-sqs \
--attributes Policy=$(echo '
{
  "Version": "2008-10-17",
  "Statement": [
    {
      "Sid": "from-sns",
      "Effect": "Allow",
      "Principal": {
        "AWS": "*"
      },
      "Action": "SQS:SendMessage",
      "Resource": "arn:aws:sqs:ap-northeast-1:123456789012:hoge-sqs",
      "Condition": {
        "ArnLike": {
          "aws:SourceArn": "arn:aws:sns:ap-northeast-1:123456789012:hoge-sns"
        }
      }
    }
  ]
}
' | jq @json )

アクセスポリシーが付与されました。SNSへメッセージ発行してみましょう。

今度はメッセージを受信することが出来ました。

さいごに

本日はSNSコンソールとSQSコンソールそれぞれからサブスクライブ操作を行った場合の違いについてまとめました。

SNSコンソールからサブスクライブする場合はSQSキューのアクセスポリシーを設定することを忘れないようにしましょう。