Cannot create QueuePolicy

Hi everyone. I’ve been trying to setup an SNS topic, and an SQS queue subscribed to that topic. According to my research this means I also need to setup a QueuePolicy that allows the SNS topic to call SendMessage on the queue.

I wrote the following serverless.yml:

service: foobar

provider:
  name: aws
  runtime: nodejs8.10
  stage: ${opt:stage, 'dev'}
  region: eu-central-1

custom:
  sns:
    name: ${self:provider.stage}-${self:service}-topic
    arn: 'arn:aws:sns:#{AWS::Region}:#{AWS::AccountId}:${self:custom.sns.name}'
  sqs:
    name: ${self:provider.stage}-${self:service}-queue
    arn: 'arn:aws:sqs:#{AWS::Region}:#{AWS::AccountId}:${self:custom.sqs.name}'
    id: 'https://sqs.#{AWS::Region}.amazonaws.com/#{AWS::AccountId}/${self:custom.sqs.name}'

plugins:
  - serverless-pseudo-parameters

resources:
  Resources:
    SnsTopic:
      Type: 'AWS::SNS::Topic'
      Properties:
        DisplayName: ${self:custom.sns.name}
        TopicName: ${self:custom.sns.name}
    SqsQueue:
      Type: 'AWS::SQS::Queue'
      Properties:
        QueueName: ${self:custom.sqs.name}
    SnsSubscription:
      Type: 'AWS::SNS::Subscription'
      Properties:
        Endpoint: ${self:custom.sqs.arn}
        Protocol: sqs
        TopicArn: ${self:custom.sns.arn}
      DependsOn:
        - SnsTopic
        - SqsQueue
    SnsQueuePolicy:
      Type: AWS::SQS::QueuePolicy
      Properties:
        PolicyDocument:
          Version: 2012-10-17
          Statement:
            - Effect: Allow
              Principal: '*'
              Action: sqs:SendMessage
              Resource: '*'
              Condition:
                ArnEquals:
                  'aws:SourceArn': ${self:custom.sns.arn}
        Queues:
          - Ref: SqsQueue
#          - ${self:custom.sqs.arn}
#          - ${self:custom.sqs.id}
      DependsOn:
        - SnsSubscription

If I leave out the AWS::SQS::QueuePolicy the resources are created successfully, so I know that works. However, that leaves me with an SNS queue subscribed to an SNS topic but the SNS topic not having the proper policies to send messages to the queue.

I’ve tried three separate values for the Queues: array. The first one is Ref: SqsQueue. However, that leaves me with the following error:

An error occurred: SnsQueuePolicy - Invalid value for the parameter Policy. (Service: AmazonSQS; Status Code: 400; Error Code: InvalidAttributeValue; Request ID: 01e73fea-4606-5c61-90b2-6c0d971bf693).

My next try was to just refer to the ARN which I have in my custom variables already anyway. This is the - ${self:custom.sqs.arn} line. This leaves me with the same error:

An error occurred: SnsQueuePolicy - Invalid value for the parameter Policy. (Service: AmazonSQS; Status Code: 400; Error Code: InvalidAttributeValue; Request ID: 645a992a-b9d4-5b52-9ba3-cacd69ba0954).

So then I went and looked at my CloudFormation stack in the AWS web console. The Physical ID of the SqsQueue resource is an https URL to the queue, equal to what you’ll see in the custom.sqs.id variable. When I refer to that in the Queues array, I get the following error:

An error occurred: SnsQueuePolicy - The specified queue does not exist for this wsdl version. (Service: AmazonSQS; Status Code: 400; Error Code: AWS.SimpleQueueService.NonExistentQueue; Request ID: a524f4e0-ae5f-5b2e-8324-a70761e45f83).

If I’m correct, using Ref: <resource> the used value is the same as the exposed physical ID in the CloudFormation stack, right? In that case the last permutation should be correct I think, but no luck.

What am I doing wrong? :slight_smile:

Shooting from the hip here, but maybe you need to include the SqsQueue in the DependsOn list for SnsQueuePolicy.

Just thinking that if it’s trying to reference the Queue and it hasn’t finished creating it yet…

1 Like

SnsSubscription depends on both the queue and the topic, and the queue policy then depends on the subscription, so indirectly it has a dependency on both of them iiuc. CloudFormation shows the policy being created last, and if I do it in two stages, first all the resources except the policy, then add the policy to serverless.yml and redeploy, it errors out it in the same way as well.

I found the issue. It seems like Version: 2012-10-17 was expanded into a full ISO 8601 timestamp. When I have time I’ll do some more digging, might be a bug.

I faced the same issue, turns out the value for Version has to be quoted (thanks to your hint on this):

Version: '2012-10-17'

or

Version: "2012-10-17"