Search code examples
aws-cloudformationamazon-sqs

Why does this SQSQueuePolicy fail to create in AWS CloudFormation?


I've created the following CloudFormation template:

AWSTemplateFormatVersion: 2010-09-09
Description: Creates all resources necessary to send SES emails & track bounces/complaints through AWS
Resources:
  IAMUser:
    Type: 'AWS::IAM::User'
    Properties:
      UserName: iam-ses-sqs
  SQSQueue:
    Type: 'AWS::SQS::Queue'
    Properties:
      QueueName: ses-queue
  SNSTopic:
    Type: 'AWS::SNS::Topic'
    Properties:
      TopicName: sns-notifications
  IAMUserPolicy:
    Type: 'AWS::IAM::Policy'
    Properties:
      PolicyName: IAM_Send_SES_Email
      PolicyDocument:
        Statement:
          - Effect: Allow
            Action:
              - 'SES:SendEmail'
              - 'SES:SendRawEmail'
            Resource: 'arn:aws:ses:*:*:identity/*'
      Users:
        - !Ref IAMUser
  SQSQueuePolicy:
    Type: 'AWS::SQS::QueuePolicy'
    Properties:
      Queues:
        - !Ref SQSQueue
      PolicyDocument:
        Statement:
          - Action:
              - 'SQS:ReceiveMessage'
              - 'SQS:DeleteMessage'
              - 'SQS:GetQueueAttributes'
            Effect: Allow
            Resource: !Ref SQSQueue
            Principal:
              AWS:
                - !Ref IAMUser
  SNSTopicSubscription:
    Type: 'AWS::SNS::Subscription'
    Properties:
      Protocol: SQS
      Endpoint: !GetAtt 
        - SQSQueue
        - Arn
      TopicArn: !Ref SNSTopic

I'd like to allow IAMUser to perform the SQS ReceiveMessage, DeleteMessage, and GetQueueAttributes actions on the SQSQueue resource. SQSQueue should also be subscribed to the SNSTopic.

When creating a stack using this template in CloudFormation, the SQSQueue, SNSTopic, SNSTopicSubscription, IAMUser, and IAMUserPolicy all create with no problem, in that order. However, the SQSQueuePolicy fails to create and generates the error message: Invalid value for the parameter Policy. (Service: AmazonSQS; Status Code: 400; Error Code: InvalidAttributeValue; Request ID: {request id})

Why is this failing, and how should I modify the template to ensure that all resources and their associated policies/subscriptions are created successfully?


Solution

  • I found two problems in your CloudFormation template.

    The first one, like Marcin said, the resource reference must be the Queue ARN and not the Queue URL.

    Resource: !GetAtt SQSQueue.Arn
    

    The second one is that your AWS reference is with your IAM user but it must be the Account ID.

    Principal:
      AWS:
        - !Ref 'AWS::AccountId'
    

    That said, I was able to create successfully the CloudFormation Stack in my account with this CloudFormation Template:

    AWSTemplateFormatVersion: 2010-09-09
    Description: Creates all resources necessary to send SES emails & track bounces/complaints through AWS
    Resources:
      IAMUser:
        Type: 'AWS::IAM::User'
        Properties:
          UserName: iam-ses-sqs
      SQSQueue:
        Type: 'AWS::SQS::Queue'
        Properties:
          QueueName: ses-queue
      SQSQueuePolicy:
        Type: 'AWS::SQS::QueuePolicy'
        Properties:
          Queues:
            - !Ref SQSQueue
          PolicyDocument:
            Statement:
              - Action:
                  - 'SQS:ReceiveMessage'
                  - 'SQS:DeleteMessage'
                  - 'SQS:GetQueueAttributes'
                Effect: Allow
                Resource: !GetAtt SQSQueue.Arn
                Principal:
                  AWS:
                    - !Ref 'AWS::AccountId'