AWS CloudFormation에 AWS Serverless Application Model(SAM) 템플릿을 배포하면 "Circular dependency between resources: [Function, Bucket, FunctionRole, FunctionUploadPermission]"와 같은 오류가 발생합니다.
간략한 설명
다음의 예시 AWS SAM 템플릿을 사용하면 CloudFormation에서 오류가 발생합니다.
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
템플릿에서 오류가 발생하는 이유는 다음과 같은 순환 종속성이 생기기 때문입니다.
- Bucket 리소스는 FunctionUploadPermission에 종속됩니다.
- FunctionUploadPermission은 Function에 종속됩니다.
- Function은 FunctionRole에 종속됩니다.
- FunctionRole은 Bucket 리소스에 종속되어 루프가 생성됩니다.
참고: 오류 메시지에서 FunctionUploadPermission 리소스는 AWS::Lambda::Permission 유형입니다. 이 리소스는 AWS::Serverless::Function에 대한 이벤트(Events) 속성이 지정되면 AWS SAM에서 자동으로 생성됩니다. FunctionRole 리소스는 AWS::IAM::Role 유형입니다. 이 리소스는 AWS::Serverless::Function에 대한 역할(Role) 속성이 지정되지 않으면 AWS SAM에서 자동으로 생성됩니다.
순환 종속성 문제를 해결하려면 버킷 리소스에 대한 동적 참조를 바꾸어 루프를 끊어야 합니다.
해결 방법
순환 종속성이 있는 CloudFormation 템플릿을 다음의 템플릿으로 교체합니다.
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
템플릿에서 정책 문의 리소스 섹션에 있는 버킷 이름은버킷 리소스의 BucketName 속성에 사용된 것과 동일한 의사 파라미터를 사용합니다. 이제 버킷을 직접 참조하지 않고 버킷 이름을 전달할 수 있습니다. 그 결과 순환 종속성 루프가 끊어져서 오류가 해결됩니다. 즉, Bucket 리소스에 따라 FunctionRole에서 발생한 순환 종속성 루프입니다.
참고: s3://mybucket/function.zip은 자신의 파일 위치로 바꿉니다.
관련 정보
Fn::Sub(내장 함수)
Ref(내장 함수)
AWS::Serverless::Function
AWS::S3::Bucket