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개 답변
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
답변함 일 년 전
  • 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.

전문가
답변함 일 년 전
0

Your ExternalTablesBucket has a DependsOn for WriteWorkingBucketPolicy

Your WriteWorkingBucketPolicy has a Ref to ExternalTablesBucket

Remove the DependsOn under ExternalTablesBucket

profile pictureAWS
전문가
kentrad
답변함 일 년 전

로그인하지 않았습니다. 로그인해야 답변을 게시할 수 있습니다.

좋은 답변은 질문에 명확하게 답하고 건설적인 피드백을 제공하며 질문자의 전문적인 성장을 장려합니다.

질문 답변하기에 대한 가이드라인

관련 콘텐츠