CloudFormation配置S3通知Lambda时加SourceArn遇报错及循环依赖如何解决
问题根源
循环依赖由两个资源的相互依赖关系触发:
- 若在
MyBucketFunctionPermission的SourceArn中使用${MyBucket},需要依赖MyBucket资源先创建完成才能获取桶名 - 同时为
MyBucket添加DependsOn: MyBucketFunctionPermission配置后,桶创建需要等待权限配置完成
两者互相等待就会触发循环依赖报错;若不配置DependsOn,S3桶创建通知时权限还未生成,就会触发400 InvalidArgument报错。
解决方案
核心思路是自定义桶名称参数,拼接SourceArn时直接使用参数值,不需要依赖桶资源创建完成,打破循环依赖。
具体修改步骤:
- 新增一个存储桶名称的自定义参数,替代CloudFormation自动生成的桶名
- 为
MyBucket显式指定桶名称,引用上述参数 MyBucketFunctionPermission的SourceArn直接通过参数拼接,不引用MyBucket资源- 保留
MyBucket的DependsOn配置,确保权限创建完成后再配置桶通知
修改后完整模板
AWSTemplateFormatVersion: '2010-09-09' Parameters: BucketName: Type: String Description: 自定义S3存储桶名称,全局唯一 Outputs: {} Resources: MyBucket: DependsOn: - MyBucketFunctionPermission Properties: BucketName: !Ref BucketName NotificationConfiguration: LambdaConfigurations: - Event: s3:ObjectCreated:* Function: Fn::GetAtt: - MyBucketFunction - Arn Type: AWS::S3::Bucket MyBucketFunction: Properties: Code: ZipFile: "def handler(event, context):\n print (event)" Handler: index.handler Role: Fn::GetAtt: - MyBucketRole - Arn Runtime: "python3.8" Type: AWS::Lambda::Function MyBucketFunctionPermission: Properties: Action: lambda:InvokeFunction FunctionName: Ref: MyBucketFunction Principal: s3.amazonaws.com SourceArn: Fn::Sub: arn:aws:s3:::${BucketName} Type: AWS::Lambda::Permission MyBucketRole: Properties: AssumeRolePolicyDocument: Statement: - Action: sts:AssumeRole Effect: Allow Principal: Service: lambda.amazonaws.com Version: '2012-10-17' Policies: - PolicyDocument: Statement: - Action: logs:* Effect: Allow Resource: '*' Version: '2012-10-17' PolicyName: Fn::Sub: my-bucket-role-policy-1234567890 Type: AWS::IAM::Role
额外说明
如果场景不允许固定桶名称,可以采用分两次部署的方式:
- 第一次部署去掉桶的NotificationConfiguration配置,创建完成后获取桶名
- 第二次部署添加上NotificationConfiguration和对应SourceArn配置
内容的提问来源于stack exchange,提问作者Justin
相关产品推荐
相关产品推荐

