Question: How do I resolve circular dependencies with AWS Serverless Application Model (SAM) templates in CloudFormation?

If I deploy an AWS Serverless Application Model (SAM) template in AWS CloudFormation, I get an error similar to the following: "Circular dependency between resources: [Function, Bucket, FunctionRole, FunctionUploadPermission]."Short descriptionYou get an error in CloudFormation if you use the following example AWS SAM template:AWSTemplateFormatVersion: '2010-09-09'Transform: AWS::Serverless-2016-10-31Description: Circular DependencyResources:  Bucket:    Type: AWS::S3::Bucket    Properties:      BucketName: !Sub "{AWS::StackName}-${AWS::Region}-${AWS::AccountId}"  Function:    Type: AWS::Serverless::Function    Properties:      CodeUri: s3://mybucket/function.zip      Runtime: nodejs12.x      Handler: index.handler      Policies:        - Version: 2012-10-17          Statement:            - Effect: Allow              Action: s3:GetObject*              Resource: !Sub "arn:aws:s3:::${Bucket}*"      Events:        Upload:          Properties:            Bucket:              Ref: Bucket            Events: s3:ObjectCreated:*          Type: S3The template produces an error because it creates the following circular dependency:The Bucket resource depends on the FunctionUploadPermission.The FunctionUploadPermission depends on the Function.The Function depends on the FunctionRole.FunctionRole depends on the Bucket resource, which creates a loop.Note: In the error message, the FunctionUploadPermission resource is of type AWS::Lambda::Permission. This resource is generated by AWS SAM automatically when the Events property for AWS::Serverless::Function is specified. The FunctionRole resource is of type AWS::IAM::Role. This resource is generated by AWS SAM automatically when the Role property for AWS::Serverless::Function is not specified.To resolve the circular dependency, you must break the loop by replacing the dynamic reference to the bucket resource.

ResolutionReplace the CloudFormation template that has a circular dependency with the following template:Permission is hereby granted, free of charge, to any person obtaining a copy of thissoftware and associated documentation files (the "Software"), to deal in the Softwarewithout restriction, including without limitation the rights to use, copy, modify,merge, publish, distribute, sublicense, and/or sell copies of the Software, and topermit persons to whom the Software is furnished to do so.THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR APARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHTHOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTIONOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THESOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.AWSTemplateFormatVersion: '2010-09-09'Transform: AWS::Serverless-2016-10-31Description: Circular DependencyResources:  Bucket:    Type: AWS::S3::Bucket    Properties:      BucketName: !Sub "${AWS::StackName}-${AWS::Region}-${AWS::AccountId}"  Function:    Type: AWS::Serverless::Function    Properties:      CodeUri: s3://mybucket/function.zip      Runtime: nodejs12.x      Handler: index.handler      Policies:        - Version: 2012-10-17          Statement:            - Effect: Allow              Action: s3:GetObject*              Resource: !Sub "arn:aws:s3:::${AWS::StackName}-${AWS::Region}-${AWS::AccountId}*"      Events:        Upload:          Properties:            Bucket:              Ref: Bucket            Events: s3:ObjectCreated:*          Type: S3In the template, the bucket namein the policy statement's Resources section uses the same pseudo parameters used in the bucket resource’s BucketName property. Now, you can pass the bucket name without referencing that bucket directly. Consequently, the error is resolved because the circular dependency loop is broken. That is, the circular dependency loop that resulted from the FunctionRole depending on the Bucket resource.Note: Replace s3://mybucket/function.zip with your file location.

Related informationFn::Sub (intrinsic function)Ref (intrinsic function)AWS::Serverless::FunctionAWS::S3::Bucket