如何跨账户结合配置 Amazon SQS 端点和 Amazon SNS 主题?

4 分钟阅读
0

我的账户 A 中有 Amazon Simple Queue Service (Amazon SQS) 队列。我想将这个队列订阅到账户 B 中的 Amazon Simple Notification Service (Amazon SNS) 主题。

简短描述

以主题所有者身份,从 Amazon SNS 主题创建订阅。或者,以队列所有者身份,从 Amazon SQS 队列创建订阅。要成功创建订阅,两种方法都必须具有相应的权限。

解决方法

**重要须知:**要以队列所有者身份订阅,请确保账户 B 中的 SNS 主题访问策略具有相应的权限。这些权限允许账户 A 中的 SQS 队列订阅 SNS 主题。要以主题所有者身份订阅,请确保账户 A 中的 SQS 队列访问策略具有相应的权限。账户 A 必须具有允许 SNS 主题发送订阅确认 URL 的权限。

以队列所有者身份订阅

要以队列所有者身份为队列订阅,请完成以下任务。

修改账户 B 中的 SNS 访问策略

完成以下步骤:

  1. 登录账户 B 中的 Amazon SNS 控制台
  2. 切换到相应的 AWS 区域。
  3. 选择主题 (Topics),然后选择您的 SNS 主题。
  4. 选择编辑 (Edit)
  5. 展开访问策略 (Access policy) 部分。
  6. 将以下访问策略复制并粘贴到 JSON 编辑器 (JSON editor) 部分:
    {
      "Statement": [
        {
          "Effect": "Allow",
          "Principal": {
            "AWS": "111122223333"
          },
          "Action": "sns:Subscribe",
          "Resource": "arn:aws:sns:Region:account-id:topic-name"
        }
      ]
    }
    **注意:**将 AWS 账户和 SNS 主题 ARN 替换为您自己的值。
  7. 选择保存 (Save)

作为队列所有者,请完成以下步骤,将账户 A 中的 SQS 队列订阅到账户 B 中的 SNS 主题:

  1. 登录账户 A 中的 Amazon SQS 控制台
  2. 切换到相应的区域。
  3. 选择队列 (Queues),然后选择您的 SQS 队列。
  4. SNS 订阅 (SNS subscriptions) 部分中,选择订阅 Amazon SNS 主题 (Subscribe to Amazon SNS topic)
  5. 指定可用于此队列的 Amazon SNS 主题 (Specify an Amazon SNS topic available for this queue) 下,选择下拉列表。然后,选择输入 Amazon SNS 主题 ARN (Enter Amazon SNS topic ARN)
  6. 可以向 Amazon SQS 队列发送通知的 Amazon SNS 主题 (An Amazon SNS topic that can send notifications to an Amazon SQS queue) 文本字段中,填写您的 SNS 主题 ARN。
  7. 选择保存 (Save)
  8. 登录账户 B 中的 Amazon SNS 控制台
  9. 选择主题 (Topics),然后选择您的 SNS 主题。
  10. 要验证账户 B 中的 SNS 主题的订阅是否已确认,请查看订阅 (Subscriptions) 部分。
    **注意:**创建订阅后,将向 SQS 队列访问策略添加一条语句。该策略允许 SNS 主题向您的队列发送消息。该策略类似于如下所示:
{
      "Sid": "topic-subscription-arn:aws:sns:Region:account-id:topic-name",
      "Effect": "Allow",
      "Principal": {
        "AWS": "*"
      },
      "Action": "SQS:SendMessage",
      "Resource": "arn:aws:sqs:Region:account-id:queue-name",
      "Condition": {
        "ArnLike": {
          "aws:SourceArn": "arn:aws:sns:Region:account-id:topic-name"
        }
      }
    }

以主题所有者身份订阅

要以主题所有者身份为队列订阅,请完成以下任务。

修改账户 A 中的 SQS 队列

完成以下步骤:

  1. 登录账户 A 中的 Amazon SQS 控制台
  2. 切换到相应的区域。
  3. 选择队列 (Queues),然后选择您的 SQS 队列。
  4. 选择编辑 (Edit)
  5. 展开访问策略 (Access policy) 部分。
  6. 将以下访问策略复制并粘贴到 JSON 编辑器:
    {
          "Sid": "Allow_SNS_topic_in_Account_B_to_Send_Message",
          "Effect": "Allow",
          "Principal": {
            "AWS": "*"
          },
          "Action": "SQS:SendMessage",
          "Resource": "arn:aws:sqs:Region:account-id:queue-name",
          "Condition": {
            "ArnLike": {
              "aws:SourceArn": "arn:aws:sns:Region:account-id:topic-name"
            }
          }
        }
    **注意:**将 SQS 队列 ARN 和 SNS 主题 ARN 替换为您自己的值。

作为主题所有者,请完成以下步骤,为您另一个账户的 SQS 队列订阅:

  1. 登录账户 B 中的 Amazon SNS 控制台
  2. 切换到相应的区域。
  3. 选择主题 (Topics),然后选择您的 SNS 主题。
  4. 订阅 (Subscriptions) 下,选择创建订阅 (Create subscription)
  5. 选择协议 (Protocol) 下拉列表,然后选择 Amazon SQS
  6. 选择创建订阅 (Create subscription)
  7. 要确认订阅,请登录账户 A 中的 Amazon SQS 控制台
  8. 选择队列 (Queues),然后选择已进行订阅的 SQS 队列。
  9. 选择发送和接收消息 (Send and receive messages)
  10. 选择轮询消息 (Poll for messages)。在消息 (Messages) 部分下,会显示一条来自 Amazon SNS 的消息。
  11. 选择消息 ID。在 SubscribeURL 下,复制引号内的 URL。
  12. 要使用 SubscriptionArn 查看 ConfirmSubscriptionResult,请将此 URL 链接粘贴到您的网页浏览器中,然后按 Enter 键。
  13. 登录账户 B 中的 Amazon SNS 控制台
  14. 选择主题 (Topics),然后选择您的 SNS 主题。
  15. 要验证订阅是否已确认,请在订阅 (Subscriptions) 下查看订阅状态。订阅状态从待确认 (Pending confirmation) 更改为已确认 (Confirmed)

**注意:**由于订阅归 SNS 账户所有,因此您无法在 SQS 控制台中看到订阅列出。

故障排除提示

要对队列问题进行故障排除,请根据您的情况完成以下任务。

我的 SQS 队列已加密

使用 AWS Key Management Service (AWS KMS) 密钥加密的 SQS 队列可以限制账户之间的访问。如果您没有为已加密的队列定义密钥,则该队列使用 AWS KMS 密钥 (SSE-KMS) 作为默认密钥。此密钥仅允许同一账户中的主体访问。有关更多信息,请参阅 Amazon SQS 中的静态加密

要访问使用 SSE-KMS 的已加密队列,请创建客户托管式 AWS KMS 密钥。然后,在密钥策略中添加权限,允许 SNS 服务进行 AWS KMS API 调用。

要允许 SNS 服务使用 GenerateDataKeyDecrypt API 方法,请在客户托管式密钥策略中添加以下语句:

{
      "Effect": "Allow",
      "Principal": {
            "Service": "sns.amazonaws.com"
      },
      "Action": [
            "kms:GenerateDataKey*",
            "kms:Decrypt"
      ],
      "Resource": "*"
}

有关更多信息,请参阅为队列(控制台)配置服务器端加密 (SSE)

当我在 Amazon SNS 控制台中创建订阅时,我的订阅在 SNS 控制台中仍处于待处理状态

要对此错误进行故障排除,请执行以下步骤:

  1. 删除您的订阅。然后,从前面步骤中的第 13 步开始。

  2. 要使用 AWS 命令行界面 (AWS CLI) 轮询您的 SQS 队列,请运行以下命令来检索 SubscriptionURL:

    aws sqs receive-message --queue-url https**:**//sqs.us-east-1.amazonaws.com/80398EXAMPLE/MyQueue --attribute-names All --message-attribute-names All --max-number-of-messages 10

    注意:如果在运行 AWS CLI 命令时收到错误,请参阅排查 AWS CLI 错误。此外,请确保您使用的是最新版本的 AWS CLI

  3. 将此 URL 复制并粘贴到浏览器中以确认进行订阅。请务必将队列 URL 替换为您自己的队列 URL。

当我复制并粘贴我的 SNS 主题访问策略时,我收到“无法设置主题访问策略”错误

当我复制并粘贴我的 SNS 主题访问策略时,收到了以下错误:

“无法设置主题访问策略。错误代码: InvalidParameter - 错误消息: 设置属性访问策略时出错。无效参数: 策略错误:null。”

请使用以下步骤对错误进行故障排除:

  1. 为了确保策略的语法正确,请将访问策略复制并粘贴到 JSON Validator 工具网站中。
  2. 查看您的访问策略,确保没有重复的语句。确保策略的第一条“Statement ID”后有逗号。

我的订阅 ID 在 Amazon SNS 控制台中显示为“Deleted”

在 SNS 和 SQS 的跨账户集成中,订阅的所有者由订阅的创建位置决定。

如果订阅是通过 SQS 账户创建的,则 SQS 是订阅的所有者。如果订阅是通过 SNS 帐户创建的,则 SNS 是订阅的所有者。

如果您从未拥有该订阅的账户中调用 Unsubscribe API,则订阅将进入 Deleted 状态。或者,如果您尝试从控制台删除订阅,则订阅将进入 Deleted 状态。当 SNS 主题订阅处于 Deleted 状态时,拥有该订阅的账户无法为同一端点重新订阅该主题。

48 小时后,Amazon SNS 会清除 Deleted 的订阅,拥有该订阅的账户可以为同一端点重新订阅该主题。

要在 48 小时之前重新订阅,请从拥有 SNS 主题的 AWS 账户调用 Subscribe API 以重新创建订阅。

最佳实践

对您的 SQS 队列的 SNS 订阅进行身份验证。进行此配置后,只有主题所有者和订阅所有者才可以从 SQS 主题取消 SNS 队列的订阅。

相关信息

将 Amazon SNS 消息发送到不同账户中的 Amazon SQS 队列

允许 Amazon Simple Storage Service (Amazon S3) 事件通知发布到主题

如何解决尝试向 Amazon SNS 主题添加订阅者时出现的授权错误?

了解数据密钥重用期

AWS 官方
AWS 官方已更新 2 个月前