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

Last updated: 2020-12-17

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 description

You get an error in AWS CloudFormation if you use the following example AWS SAM template:

AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: Circular Dependency
Resources:
  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: S3

The template produces an error because it creates the following circular dependency:

  1. The Bucket resource depends on the FunctionUploadPermission.
  2. The FunctionUploadPermission depends on the Function.
  3. The Function depends on the FunctionRole.
  4. FunctionRole depends on the Bucket resource, which creates a loop.

To resolve the circular dependency, you must break the loop by replacing the dynamic reference to the bucket resource.

Resolution

Replace the AWS 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 this
software and associated documentation files (the "Software"), to deal in the Software
without restriction, including without limitation the rights to use, copy, modify,
merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
permit 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 A
PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: Circular Dependency
Resources:
  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: S3

In the preceding template, the bucket name in the function resource’s policy statement uses the same pseudo parameters used in the bucket resource’s BucketName property to reference the bucket resource without dynamically referencing it.

Note: Replace s3://mybucket/function.zip with your file location.


Did this article help?


Do you need billing or technical support?