如何使用 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。