circular dependency between resources in CloudFormation template

0

I am facing circular dependency between resources in CloudFormation template when i try to deploy following template -

Resources:

  ExternalTablesRolesStack:
    Type: AWS::CloudFormation::Stack
    Properties:
      TemplateURL: !Sub "${LibStackPath}/roles/template.yaml"

  ExternalTablesBucket:
    # http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-s3-bucket.html
    Type: AWS::S3::Bucket
    DependsOn: WriteWorkingBucketPolicy
    Properties:
      LifecycleConfiguration:
        Rules:
          - Id: LifeCycleRule
            ExpirationInDays: 7
            Status: Enabled

  ParameterExternalTablesBucket:
    # http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ssm-parameter.html
    Type: AWS::SSM::Parameter
    DependsOn: ExternalTablesBucket
    Properties:
      Type: String
      Value: !Ref ExternalTablesBucket
      Name: !Sub '/${Stage}/AWS_EXTERNAL_TABLES_BUCKET'

  ExternalTableColumnsParser:
      # http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-lambda-function.html
      Type: AWS::Serverless::Function
      DependsOn: [ExternalTablesBucket, WriteWorkingBucketPolicy]
      Properties:
        Environment:
          Variables:
            Stage: !Ref Stage
        Events:
          OnPlaceFileEvent:
            Type: S3
            Properties:
              Bucket: !Ref ExternalTablesBucket  # must be defined in same template
              Events: s3:ObjectCreated:Put
              Filter:
                S3Key:
                  Rules:
                    - Name: suffix
                      Value: .csv
        Handler: schema_parser.app.lambda_handler
        Role: !GetAtt ExternalTablesParserRole.Arn

  WriteWorkingBucketPolicy:
    Type: AWS::IAM::Policy
    Properties:
      PolicyName: AllowWriteInternalBucket
      PolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: Allow
            Action:
              - s3:PutObject
              - s3:DeleteObject
            Resource:
              - !Sub ["arn:aws:s3:::${Name}/*", Name: !Ref ExternalTablesBucket]
      Roles:
        - !GetAtt ExternalTablesRolesStack.Outputs.ServerlessFunctionRoleName

then giving error as

Circular dependency between resources: [ExternalTablesBucket,ExternalTableColumnsParserOnPlaceFileEventPermission,ExternalTableColumnsParser, WriteWorkingBucketPolicy,ParameterExternalTablesBucket]

Is there any correct way to fix it?

3 Answers
1

After try some trial for fix template I had found correct way to prevent circular dependency -

`stack operations go through the following order:

  1. create ExternalTablesRolesStack
  2. create ExternalTableColumnsParser
  3. create ExternalTableColumnsParserOnPlaceFileEventPermission
  4. create ExternalTablesBucket
  5. create WriteWorkingBucketPolicy ExternalTablesBucket comes later than ExternalTableColumnsParser. But old template let ExternalTableColumnsParser to depend on ExternalTablesBucket `

Here is the correct template -

Resources:

  ExternalTablesRolesStack:
    Type: AWS::CloudFormation::Stack
    Properties:
      TemplateURL: !Sub "${LibStackPath}/roles/template.yaml"

  ExternalTablesBucket:
    # http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-s3-bucket.html
    Type: AWS::S3::Bucket
    Properties:
      LifecycleConfiguration:
        Rules:
          - Id: LifeCycleRule
            ExpirationInDays: 7
            Status: Enabled

  ExternalTableColumnsParser:
      # http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-lambda-function.html
      Type: AWS::Serverless::Function
      Properties:
        Environment:
          Variables:
            Stage: !Ref Stage
        Events:
          OnPlaceFileEvent:
            Type: S3
            Properties:
              Bucket: !Ref ExternalTablesBucket  # must be defined in same template
              Events: s3:ObjectCreated:Put
              Filter:
                S3Key:
                  Rules:
                    - Name: suffix
                      Value: .csv
        Handler: schema_parser.app.lambda_handler
        Role: !GetAtt ExternalTablesRolesStack.Outputs.ServerlessFunctionRole

  WriteWorkingBucketPolicy:
    Type: AWS::IAM::Policy
    Properties:
      PolicyName: AllowWriteInternalBucket
      PolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: Allow
            Action:
              - s3:PutObject
              - s3:DeleteObject
            Resource:
              - !Sub ["arn:aws:s3:::${Name}/*", Name: !Ref ExternalTablesBucket]
      Roles:
        - !GetAtt ExternalTablesRolesStack.Outputs.ServerlessFunctionRoleName
deepak
answered a year ago
  • Good news! So you removed all the DependsOn as I suggested - please Accept my answer if you have a moment, to help other people find it.

0

Have a good look at your "DependsOn" statements. They should be used sparingly, only in situations where CloudFormation needs to be told that resource A must be created before resource B or else creation of resource B will fail.

Looking at for example:

  ParameterExternalTablesBucket:
    # http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ssm-parameter.html
    Type: AWS::SSM::Parameter
    DependsOn: ExternalTablesBucket

You shouldn't have a DependsOn here because there is no need for the bucket to exist when you're creating the SSM parameter. You're just setting a string value in the parameter that has no meaning to CloudFormation.

Basically, remove all your DependsOn statements and you'll be able to tell by the CloudFormation errors if it turns out you really need any.

EXPERT
answered a year ago
0

Your ExternalTablesBucket has a DependsOn for WriteWorkingBucketPolicy

Your WriteWorkingBucketPolicy has a Ref to ExternalTablesBucket

Remove the DependsOn under ExternalTablesBucket

profile pictureAWS
EXPERT
kentrad
answered a year ago

You are not logged in. Log in to post an answer.

A good answer clearly answers the question and provides constructive feedback and encourages professional growth in the question asker.

Guidelines for Answering Questions