Circular dependencies in AWS SAM Policies
I’m trying to tighten up the policies of my AWS Lambda function so that it only has access to the one S3 bucket that it needed, so I added an S3CrudPolicy with the BucketName referencing the bucket that’s defined in the template.
The relevant part of template.yaml looks like this:
Resources:
ImagesBucket:
Type: AWS::S3::Bucket
Properties:
BucketName: !Sub "${ProjectName}-${UniqueKey}-images"
ResizeFunction:
Type: AWS::Serverless::Function
Properties:
FunctionName: resize
# ...
Events:
CreateThumbnailEvent:
Type: S3
Properties:
Bucket: !Ref ImagesBucket
Events: s3:ObjectCreated:*
Policies:
- S3CrudPolicy:
BucketName: !Ref ImagesBucket
However, this creates an error:
Failed to create the changeset: Waiter ChangeSetCreateComplete failed: Waiter encountered
a terminal failure state Status: FAILED. Reason: Circular dependency between resources:
[ImagesBucket, ResizeFunctionRole, ResizeFunction, ResizeFunctionCreateThumbnailEventPermission]
(Who is this waiter anyway? This isn’t a restaurant!)
Solution
To solve this, instead of referencing ImageBucket in the BucketName of the S3CrudPolicy, we can put the image name in directly. This is not the ARN, just the name, so we can do:
Policies:
- S3CrudPolicy:
BucketName: !Sub "${ProjectName}-${UniqueKey}-images"
This works because by setting the BucketName to a string, there’s no dependency on the ImagesBucket resource itself, so it all works.