SNS主题不发布到SQS

use*_*875 11 amazon-sqs amazon-web-services amazon-sns

我正在尝试使用SNS和SQS对分布式应用程序进行原型设计.我有这个主题:

arn:aws:sns:us-east-1:574008783416:us-east-1-live-auction

和这个队列:

arn:aws:sqs:us-east-1:574008783416:queue4

我使用JS Scratchpad创建了队列.我使用控制台添加了订阅.我使用暂存器将AddPermission添加到队列中.队列策略现在是:

{  
   "Version":"2008-10-17",
   "Id":"arn:aws:sqs:us-east-1:574008783416:queue4/SQSDefaultPolicy",
   "Statement":[  
      {  
         "Sid":"RootPerms",
         "Effect":"Allow",
         "Principal":{  
            "AWS":"574008783416"
         },
         "Action":"SQS:*",
         "Resource":"arn:aws:sqs:us-east-1:574008783416:queue4"
      }
   ]
}
Run Code Online (Sandbox Code Playgroud)

我有一个关于同一主题的电子邮件订阅,电子邮件很好地到达,但邮件从未到达队列.我已经尝试使用Scratchpad将SendMessage直接发送到队列 - 而不是通过SNS - 它工作正常.任何想法为什么它不会发送到队列?

Sky*_*son 15

这是在AWS论坛上发布的:https://forums.aws.amazon.com/thread.jspa? messageID = 202798

然后我给SNS主题授予了向SQS队列发送消息的权限.这里的诀窍是允许所有校长.SNS不会从您的帐户ID发送 - 它有自己的帐户ID.

  • 您需要限制对 sourceArn 的访问:https://docs.aws.amazon.com/sns/latest/dg/sns-access-policy-use-cases.html#sns-publish-messages-to-sqs -队列 (3认同)

Flo*_*n D 15

我刚刚经历过这个,并花了一段时间才弄清楚原因:

如果我从 SNS 控制台创建 SQS 订阅,它不会向 SQS 访问策略添加必要的权限。

如果我在 SQS 控制台中创建对同一 SNS 的订阅,它会执行此操作。


spg*_*spg 11

添加到 Skyler 的回答中,如果像我一样您对允许任何主体 ( Principal: '*')的想法感到畏缩,您可以将主体限制为 SNS:

Principal:
  Service: sns.amazonaws.com
Run Code Online (Sandbox Code Playgroud)

尽管此行为未记录在案,但它确实有效。


Sho*_*ter 9

大多数答案(@spg 答案旁边)都建议使用principal: *- 这是非常危险的做法,它会将您的 SQS 暴露给全世界。

来自AWS 文档

对于基于资源的策略,例如 Amazon S3 存储桶策略,principal 元素中的通配符 (*) 指定所有用户或公共访问。
我们强烈建议您不要在角色信任策略的 Principal 元素中使用通配符,除非您通过策略中的 Condition 元素限制访问。否则,您分区中任何账户中的任何 IAM 用户都可以访问该角色。

因此,强烈不建议使用此主体。

相反,您需要将 sns 服务指定为您的主体:

"Principal": {
        "Service": "sns.amazonaws.com"
},
Run Code Online (Sandbox Code Playgroud)

示例政策:

{
  "Version": "2012-10-17",
  "Id": "Policy1596186813341",
  "Statement": [
    {
      "Sid": "Stmt1596186812579",
      "Effect": "Allow",
      "Principal": {
        "Service": "sns.amazonaws.com"
      },
      "Action": [
        "sqs:SendMessage",
        "sqs:SendMessageBatch"
      ],
      "Resource": "Your-SQS-Arn"
    }
  ]
}
Run Code Online (Sandbox Code Playgroud)

使用此策略,sns 将能够向您的 SQS 发送消息。

更多的权限为SQS但是从我所看到的SendMessageSendMessageBatch应该SNS-> SQS订阅新资料是不够的。

  • 这是一个很好的答案。当我在AWS控制台中将SNS连接到SQS时,我感到很惊讶,它不会自动执行权限部分。 (8认同)

kic*_*hik 5

这是Skyler答案的完整CloudFormation示例

"MyQueue": {
  "Type": "AWS::SQS::Queue"
},
"QueuePolicy": {
  "Type": "AWS::SQS::QueuePolicy",
  "Properties": {
    "Queues": [
      {
        "Ref": "MyQueue"
      }
    ],
    "PolicyDocument": {
      "Version": "2012-10-17",
      "Statement": [
        {
          "Sid": "allow-sns-messages",
          "Effect": "Allow",
          "Principal": "*",
          "Action": "sqs:SendMessage",
          "Condition": {
            "ArnEquals": {
              "aws:SourceArn": {
                "Ref": "MyTopic"
              }
            }
          }
        }
      ]
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

Amazon在“将Amazon SNS消息发送到Amazon SQS队列”文档中有更多选项。

  • 据我所知,该语句需要包含一个 Resource 属性:"Resource": { "Fn::GetAtt": ["MyQueue", "Arn" ] }, (3认同)

Ula*_*ach 5

与提到的其他答案一样,您必须选择加入并授予此 SNS 主题发布到您的 SQS 队列的权限。

如果您使用 terraform,则可以使用sqs_queue_policy资源。

这是一个例子

resource "aws_sqs_queue_policy" "your_queue_policy" {
    queue_url = "${aws_sqs_queue.your_queue.id}"

    policy = <<POLICY
{
  "Version": "2012-10-17",
  "Id": "sqspolicy",
  "Statement": [
    {
      "Sid": "First",
      "Effect": "Allow",
      "Principal": "*",
      "Action": "sqs:SendMessage",
      "Resource": "${aws_sqs_queue.your_queue.arn}",
      "Condition": {
        "ArnEquals": {
          "aws:SourceArn": "${aws_sns_topic.your_topic.arn}"
        }
      }
    }
  ]
}
POLICY
}
Run Code Online (Sandbox Code Playgroud)