gpt4 book ai didi

amazon-web-services - 无法在现有 S3 存储桶中放置通知事件来触发 CloudFormation Lambda

转载 作者:行者123 更新时间:2023-12-03 07:14:00 25 4
gpt4 key购买 nike

我正在使用 SAM 将“手工构建”的 AWS 基础设施堆栈迁移到 CloudFormation模板。我已成功迁移几乎所有资源,但在迁移 S3 存储桶方面遇到了障碍。我遇到的问题是处理 S3 存储桶事件(例如对象创建对象删除)的 Lambda 函数。

我研究并尝试了多种选项,包括将 Lambda 触发事件附加到堆栈创建时预先存在的 S3 存储桶,但是 I learned that this was not possible因为 S3 存储桶不是正在构建的 CloudFormation 堆栈的一部分。

接下来,我尝试在 CloudFormation 堆栈中创建一个新存储桶并附加事件对象。起初,我尝试使用现有的 SAM 模板快捷方式在 S3 存储桶和 Lambda 之间创建事件,但这样做会产生资源之间的循环依赖错误,结果是由于 circular permissions required between the bucket and the lambda .

为了解决循环依赖问题,我创建了一个辅助自定义资源 Lambda,该资源在使用 S3 API 直接 PUT 通知的 CloudFormation 堆栈创建过程中运行。我尝试遵循 first post 中提供的示例解决方案,其中使用自定义资源将事件放入 S3 存储桶中。使用此方法,我的 CloudFormation 构建始终失败,并显示相同的错误消息:无法验证以下目标配置。为了解决这个问题我找到了this solution在 StackOverflow 上,并将 AWS::Lambda::PermissionAWS::S3::BucketPolicy 资源添加到我的 CloudFormation 模板中。尽管我进行了更改,错误仍然发生。

我错过了什么?

这是我的 template.yaml 的片段:

  IngestClip:
Type: AWS::Serverless::Function
Properties:
Role: !GetAtt LambdaExecutionRole.Arn
Architectures:
- arm64
CodeUri: functions/ingestClip/
VpcConfig:
SecurityGroupIds:
- !Ref LambdaSecurityGroup
SubnetIds:
- !Ref PrivateSubnet1
- !Ref PrivateSubnet2

IngestClipPermission:
Type: AWS::Lambda::Permission
Properties:
FunctionName: !Ref ConfigureLambdaS3Event
Action: "lambda:InvokeFunction"
Principal: s3.amazonaws.com
SourceAccount: !Ref AWS::AccountId
SourceArn: !GetAtt IngestBucket.Arn

IngestBucket:
Type: AWS::S3::Bucket

IngestBucketPolicy:
Type: AWS::S3::BucketPolicy
Properties:
Bucket: !Ref IngestBucket
PolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Action:
- 's3:PutBucketNotification'
Resource: !Sub "arn:aws:s3:::${IngestBucket}"
Principal:
AWS: !GetAtt LambdaExecutionRole.Arn

ConfigureLambdaS3Event:
DependsOn:
- NATRoute
- InternetRoute
Type: AWS::Lambda::Function
Properties:
Handler: index.handler
Runtime: nodejs14.x
Role: !GetAtt LambdaExecutionRole.Arn
Timeout: 60
Architectures:
- arm64
VpcConfig:
SecurityGroupIds:
- !Ref LambdaSecurityGroup
SubnetIds:
- !Ref PrivateSubnet1
- !Ref PrivateSubnet2
Layers:
- !Ref NodeDependencies
- !Ref Common
Code:
ZipFile: |
const aws = require('aws-sdk');
const s3 = new aws.S3({ apiVersion: '2006-03-01', signatureVersion: 'v4' });

const { withCustomResourceResponder } = require('utility/customResource.js');
const { decorate } = require('utility/decorator.js');

exports.handler = decorate([
withCustomResourceResponder({
shortCircuitOnDeleteRequest: true
})
], async (event, context) => {
let { Bucket, Function, Event, Filters } = event.ResourceProperties;
let params = {
Bucket: Bucket,
NotificationConfiguration: {
LambdaFunctionConfigurations: [
{
LambdaFunctionArn: Function,
Events: [
Event
],
Filter: {
Key: {
FilterRules: JSON.parse(Filters)
}
}
}
]
}
};
console.log('params:', JSON.stringify(params, null, 2));
return await s3.putBucketNotificationConfiguration(params).promise();
});


ConfigureIngestClipEventOnBuild:
DependsOn:
- ConfigureLambdaS3Event
- ConfigureLambdaS3EventIngestBucketAccess
- IngestBucket
- IngestClip
Type: AWS::CloudFormation::CustomResource
Properties:
ServiceToken: !GetAtt ConfigureLambdaS3Event.Arn
Bucket: !Ref IngestBucket
Function: !GetAtt IngestClip.Arn
Event: 's3:ObjectCreated:*'
Filters: '[{"Name": "suffix", "Value": ".wav" }]'

最佳答案

刚刚发现我的解决方案存在问题:我未正确配置 AWS::Lambda::Permission。它不应该向支持自定义资源的函数授予权限,而应该向 S3 触发器附加的实际 lambda 授予权限,如下所示:

  IngestClipPermission:
Type: AWS::Lambda::Permission
Properties:
FunctionName: !Ref IngestClip
Action: "lambda:InvokeFunction"
Principal: s3.amazonaws.com
SourceAccount: !Ref AWS::AccountId
SourceArn: !GetAtt IngestBucket.Arn

进行此更改解决了问题,并且事件已成功创建。

关于amazon-web-services - 无法在现有 S3 存储桶中放置通知事件来触发 CloudFormation Lambda,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70511630/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com