如何使用 aws-sdk 从 lambda 函数中删除 s3 对象
How to delete an s3 object from a lambda function using aws-sdk
我正在尝试从 s3 存储桶中删除一个对象,但无论我做什么,删除请求总是以超时结束。我在想我的权限配置不正确,或者我使用的 aws-sdk 不正确。
这是我在 aws-cdk 中定义的 lambda 函数创建:
this.appsyncS3LambdaResolver = new NodejsFunction(
this,
"appsyncS3LambdaResolver",
{
memorySize: 1024,
handler: "handler",
runtime: lambda.Runtime.NODEJS_14_X,
timeout: cdk.Duration.seconds(5),
entry: __dirname + "/../../lambda-fns/AppsyncS3LambdaResolver/index.ts",
environment: {
SECRET_NAME: props.rdsSecretName || "",
SECRET_VALUE: props.rdsSecretValue || "",
S3_BUCKET_NAME: props.s3bucket.bucketName,
S3_BUCKET_URL: props.s3bucket.bucketWebsiteUrl,
},
bundling: {
externalModules: ["aws-sdk"],
nodeModules: ["pg"],
},
vpc: props.vpc,
vpcSubnets: { subnetType: ec2.SubnetType.ISOLATED },
securityGroups: [props.lambdaAccessToRDSSecurityGroup],
}
);
// Give appsyncS3LambdaResolver access to put to S3 bucket (which enables it to make presigned urls)
// and delete
props.s3bucket.grantPut(this.appsyncS3LambdaResolver);
props.s3bucket.grantDelete(this.appsyncS3LambdaResolver);
这是我创建的 s3 存储桶:
this.s3bucket = new s3.Bucket(this, "s3-bucket", {
// bucketName: 'my-bucket',
removalPolicy: cdk.RemovalPolicy.DESTROY,
autoDeleteObjects: true,
versioned: false,
publicReadAccess: false,
encryption: s3.BucketEncryption.S3_MANAGED,
cors: [
{
allowedMethods: [s3.HttpMethods.GET, s3.HttpMethods.PUT],
allowedOrigins: props.isProd
? [] // tbd
: ["http://localhost:3000", "http://localhost:3000/*"],
allowedHeaders: ["*"],
},
],
lifecycleRules: [
{
abortIncompleteMultipartUploadAfter: cdk.Duration.days(90),
expiration: cdk.Duration.days(365),
transitions: [
{
storageClass: s3.StorageClass.INFREQUENT_ACCESS,
transitionAfter: cdk.Duration.days(30),
},
],
},
],
});
this.s3bucket.addToResourcePolicy(
new iam.PolicyStatement({
sid: "allow deleting objects from s3 bucket /public/*",
effect: iam.Effect.ALLOW,
principals: [new iam.AnyPrincipal()],
actions: ["s3:DeleteObject"],
resources: [this.s3bucket.bucketArn + "/public/*"],
})
);
以及未删除的实际 lambda 函数代码:
for (let i = 0; i < result.rows[0].num_media; i++) {
const params = {
Bucket: process.env.S3_BUCKET_NAME,
Key: `public/reviewmedia/${reviewId}/${i}`,
};
console.log("params:", params);
const res = await s3.deleteObject(params).promise();
console.log(res);
}
我有两个权限授予我的 lambda 函数从 s3 存储桶中删除的权限(s3bucket.grantDelete() 和 s3 存储桶上的策略),但它们似乎都不起作用。在这里,我给了我的政策等同于 principals: "*" 但这也没有解决它。我不确定我的配置有什么问题...非常感谢您的建议。
通常超时错误与连接问题有关。
对于 VPC 中的 lambda 运行,确保关联的 SG 允许出站流量,并检查 lambda 子网是否有连接到 S3 的路由(通过 public 子网的 IGW,Nat Gateway/Nat 私有子网或 S3 VPC 端点的实例,无需前面提到的选项即可私下连接到 S3。
我正在尝试从 s3 存储桶中删除一个对象,但无论我做什么,删除请求总是以超时结束。我在想我的权限配置不正确,或者我使用的 aws-sdk 不正确。
这是我在 aws-cdk 中定义的 lambda 函数创建:
this.appsyncS3LambdaResolver = new NodejsFunction(
this,
"appsyncS3LambdaResolver",
{
memorySize: 1024,
handler: "handler",
runtime: lambda.Runtime.NODEJS_14_X,
timeout: cdk.Duration.seconds(5),
entry: __dirname + "/../../lambda-fns/AppsyncS3LambdaResolver/index.ts",
environment: {
SECRET_NAME: props.rdsSecretName || "",
SECRET_VALUE: props.rdsSecretValue || "",
S3_BUCKET_NAME: props.s3bucket.bucketName,
S3_BUCKET_URL: props.s3bucket.bucketWebsiteUrl,
},
bundling: {
externalModules: ["aws-sdk"],
nodeModules: ["pg"],
},
vpc: props.vpc,
vpcSubnets: { subnetType: ec2.SubnetType.ISOLATED },
securityGroups: [props.lambdaAccessToRDSSecurityGroup],
}
);
// Give appsyncS3LambdaResolver access to put to S3 bucket (which enables it to make presigned urls)
// and delete
props.s3bucket.grantPut(this.appsyncS3LambdaResolver);
props.s3bucket.grantDelete(this.appsyncS3LambdaResolver);
这是我创建的 s3 存储桶:
this.s3bucket = new s3.Bucket(this, "s3-bucket", {
// bucketName: 'my-bucket',
removalPolicy: cdk.RemovalPolicy.DESTROY,
autoDeleteObjects: true,
versioned: false,
publicReadAccess: false,
encryption: s3.BucketEncryption.S3_MANAGED,
cors: [
{
allowedMethods: [s3.HttpMethods.GET, s3.HttpMethods.PUT],
allowedOrigins: props.isProd
? [] // tbd
: ["http://localhost:3000", "http://localhost:3000/*"],
allowedHeaders: ["*"],
},
],
lifecycleRules: [
{
abortIncompleteMultipartUploadAfter: cdk.Duration.days(90),
expiration: cdk.Duration.days(365),
transitions: [
{
storageClass: s3.StorageClass.INFREQUENT_ACCESS,
transitionAfter: cdk.Duration.days(30),
},
],
},
],
});
this.s3bucket.addToResourcePolicy(
new iam.PolicyStatement({
sid: "allow deleting objects from s3 bucket /public/*",
effect: iam.Effect.ALLOW,
principals: [new iam.AnyPrincipal()],
actions: ["s3:DeleteObject"],
resources: [this.s3bucket.bucketArn + "/public/*"],
})
);
以及未删除的实际 lambda 函数代码:
for (let i = 0; i < result.rows[0].num_media; i++) {
const params = {
Bucket: process.env.S3_BUCKET_NAME,
Key: `public/reviewmedia/${reviewId}/${i}`,
};
console.log("params:", params);
const res = await s3.deleteObject(params).promise();
console.log(res);
}
我有两个权限授予我的 lambda 函数从 s3 存储桶中删除的权限(s3bucket.grantDelete() 和 s3 存储桶上的策略),但它们似乎都不起作用。在这里,我给了我的政策等同于 principals: "*" 但这也没有解决它。我不确定我的配置有什么问题...非常感谢您的建议。
通常超时错误与连接问题有关。
对于 VPC 中的 lambda 运行,确保关联的 SG 允许出站流量,并检查 lambda 子网是否有连接到 S3 的路由(通过 public 子网的 IGW,Nat Gateway/Nat 私有子网或 S3 VPC 端点的实例,无需前面提到的选项即可私下连接到 S3。