I have been successfully putting IAM role statements in my serverless.yml for S3 access for some time and assumed everything would work similarly when I added SQS. I took the very simple arn:aws:s3::: and replaced the s3 with SQS, as you can see below:
iam:
role:
statements:
- Effect: 'Allow'
Action:
- 's3:ListBucket'
Resource:
Fn::Join:
- ''
- - 'arn:aws:s3:::'
- mahtestbucket
- Effect: 'Allow'
Action:
- 's3:GetObject'
Resource:
Fn::Join:
- ''
- - 'arn:aws:s3:::'
- mahtestbucket
- '/*'
- Effect: 'Allow'
Action:
- 's3:ListBucket'
Resource:
Fn::Join:
- ''
- - 'arn:aws:s3:::'
- mahfailbucket
- Effect: 'Allow'
Action:
- 's3:PutObject'
Resource:
Fn::Join:
- ''
- - 'arn:aws:s3:::'
- mahfailbucket
- '/*'
- Effect: 'Allow'
Action:
- 'sqs:SendMessage'
- 'sqs:GetQueueUrl'
- 'sqs:GetQueueAttributes'
Resource:
Fn::Join:
- ''
- - 'arn:aws:sqs:::'
- mahqueue
This deploys with no errors. I can see the policy statement but it just doesn't work. The lambda function fails when it attempts to access the SQS resource.
I decided to post this with my own answer since it took me a few hours of wasted time to verify the policy was being created and determine what is going on. I believe since S3 does not usually include a region definition, and buckets are global, the simpler specification works. SQS and probably most other resources, however, need these things. Once I determined this might be the issue, it took a little research to get the correct syntax working:
- Effect: 'Allow'
Action:
- 'sqs:SendMessage'
- 'sqs:GetQueueUrl'
- 'sqs:GetQueueAttributes'
- 'sqs:ListQueues'
Resource:
Fn::Join:
- ''
- - !Sub 'arn:aws:sqs:${AWS::Region}:${AWS::AccountId}:'
- mahqueue