AWS SQS未收到SNS消息

asd*_*sdf 4 bash amazon-web-services aws-cli

我创建了一个SNS主题,该主题通过cli发布来自Cloudformation的所有信息。但是,当我检查队列时,它没有收到任何SNS消息。我通过订阅我的电子邮件来验证SNS是否可以正常工作,因此问题似乎出在队列和SNS之间。但是,我的语法找不到任何问题。据我所知,我完全遵循了Amazon的文档。

重击:

#SNS parameters
SNS_NAME="${NAME}_SNS"
SQS_NAME="${NAME}_SQS"

#Create SNS topic to send cloudformation notifications to
SNS_ARN=`aws sns create-topic --name ${SNS_NAME} | jq -r '.TopicArn'`

#Create SQS to send SNS to (holding SNS messages for lambda -^ up)
SQS_URL=`aws sqs create-queue --queue-name ${SQS_NAME} | jq -r '.QueueUrl'`
SQS_ARN=`aws sqs get-queue-attributes --queue-url ${SQS_URL} --attribute-names QueueArn | jq -r '.Attributes .QueueArn'`

#subscribe the queue to the notifications
aws sns subscribe --topic-arn ${SNS_ARN} --protocol sqs --notification-endpoint ${SQS_ARN}
aws sns subscribe --topic-arn ${SNS_ARN} --protocol email-json --notification-endpoint ${EMAIL}

#Create the stack which kicks everything else off-
aws cloudformation create-stack $REGIONTEXT $ITYPETEXT --capabilities CAPABILITY_IAM --template-url https://${BUCKETNAME}.s3.amazonaws.com/${TEMPLATE} --notification-arns ${SNS_ARN} --stack-name $NAME --parameters ParameterKey=SNSARN,ParameterValue=${SNS_ARN} ParameterKey=Bucket,ParameterValue=${BUCKETNAME} ${PARAMTEXT} ${EXTRAARGS}
Run Code Online (Sandbox Code Playgroud)

小智 9

就我而言,SQS 无法从 SNS 接收消息,因为 SQS 已开启加密。当我在 SQS 上关闭加密时,它开始工作了!

此 AWS 文档解释了如何启用与加密 SQS 队列的 SNS 兼容性:

https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-server-side-encryption.html#compatibility-with-aws-services

SNS 需要额外的权限才能使用 KMS 密钥为队列加密消息。


Mar*_*k B 6

看起来您没有授予SNS主题发布到SQS队列的权限。请看本演练中的步骤2 。您需要将这样的策略添加到SQS队列中:

{
  "Version":"2012-10-17",
  "Statement":[
    {
      "Sid":"MySQSPolicy001",
      "Effect":"Allow",
      "Principal":"*",
      "Action":"sqs:SendMessage",
      "Resource":"arn:aws:sqs:us-east-1:123456789012:MyQueue",
      "Condition":{
        "ArnEquals":{
          "aws:SourceArn":"arn:aws:sns:us-east-1:123456789012:MyTopic"
        }
      }
    }
  ]
}
Run Code Online (Sandbox Code Playgroud)

将ARN替换为您的主题和队列的ARN。


asd*_*sdf 5

谢谢Mark B的回答。它为开始这项工作提供了开始。但是,为了使策略文档通过CLI起作用,文档中没有涉及一些怪癖。

  1. 尝试将json直接传递到命令中的--attributes标志时,会发生各种错误aws sqs set-queue-attributes。由于某种原因,它要求将修改的json包含在.jsoncli引用的文档中。
  2. .json提供给cli 的文件中,"Policy"值(嵌套json)中的所有双引号都必须转义(即{ \"Statement\": \"HelloWorld\" })。如果不这样做,将验证错误。我最终需要使用ascii转义字符来正确格式化输出(\x5C)。
  3. 必须file://local-location--attributes标志中使用来引用json文件。如果不遵循该规则,则会引发错误。

请参阅以下我用作参考的元素:

load_sqs.sh:

SQS_POLICY=
sqs-policy()
{
#First param is the queue arn, second param is the topic arn
SQS_POLICY=`printf '{ "Policy": "{\x5C\"Version\x5C\":\x5C\"2012-10-17\x5C\",\x5C\"Statement\x5C\":[{\x5C\"Sid\x5C\":\x5C\"CloudformationLambdaSQSPolicy\x5C\",\x5C\"Effect\x5C\":\x5C\"Allow\x5C\",\x5C\"Principal\x5C\":\x5C\"*\x5C\",\x5C\"Action\x5C\":\x5C\"sqs:SendMessage\x5C\",\x5C\"Resource\x5C\":\x5C\"%s\x5C\",\x5C\"Condition\x5C\":{\x5C\"ArnEquals\x5C\":{\x5C\"aws:SourceArn\x5C\":\x5C\"%s\x5C\"}}}]}" }' "$1" "$2"`
`echo $SQS_POLICY > $PWD/sqs-policy.json`
}

#SNS parameters
SNS_NAME="${NAME}_SNS"
SQS_NAME="${NAME}_SQS"

#Create SNS topic to send cloudformation notifications to
SNS_ARN=`aws sns create-topic --name ${SNS_NAME} | jq -r '.TopicArn'`

#Create SQS to send SNS to (holding SNS messages for lambda -^ up)
SQS_URL=`aws sqs create-queue --queue-name ${SQS_NAME} | jq -r '.QueueUrl'`
SQS_ARN=`aws sqs get-queue-attributes --queue-url ${SQS_URL} --attribute-names QueueArn | jq -r '.Attributes .QueueArn'`

#Add necessary SQS <--> SNS permissions
sqs-policy ${SQS_ARN} ${SNS_ARN}
`aws sqs set-queue-attributes --queue-url ${SQS_URL} --attributes file://sqs-policy.json`

#subscribe the queue to the notifications
aws sns subscribe --topic-arn ${SNS_ARN} --protocol sqs --notification-endpoint ${SQS_ARN}
Run Code Online (Sandbox Code Playgroud)

sqs-policy.json:

{ "Policy": "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Sid\":\"CloudformationLambdaSQSPolicy\",\"Effect\":\"Allow\",\"Principal\":\"*\",\"Action\":\"sqs:SendMessage\",\"Resource\":\"ResourceARN\",\"Condition\":{\"ArnEquals\":{\"aws:SourceArn\":\"SourceARN\"}}}]}" }
Run Code Online (Sandbox Code Playgroud)


小智 5

如果 SQS 已加密,则将消息推送到队列的事件必须遵循以下步骤

多个 AWS 服务将事件发送到 Amazon SQS 队列。要允许这些事件源使用加密队列,您必须执行以下步骤。

  • 使用客户托管的 CMK。

    要允许 AWS 服务拥有 kms:GenerateDataKey* 和 kms:Decrypt 权限,请将以下语句添加到 CMK 策略。

    { "Version": "2012-10-17", "Statement": [{ "Effect": "Allow", "Principal": { "Service": "service.amazonaws.com" }, "Action": [ "kms:GenerateDataKey*", "kms:Decrypt" ], "Resource": "*" }] }

  • 使用 CMK 的 ARN 创建新的 SSE 队列或配置现有的 SSE 队列。

    向事件源提供加密队列的 ARN。

对于 sns 用 sns.amazonaws.com 替换服务部分

"Principal": { "Service": "sns.amazonaws.com" }