如何在 CDK 中将 API Gateway 与 s3 集成

Arm*_*sta 3 amazon-s3 amazon-web-services aws-api-gateway aws-cdk

在控制台中执行此操作的文档非常清楚,https://docs.aws.amazon.com/apigateway/latest/developerguide/integrating-api-with-aws-services-s3.html,但在 CDK 中复制确实是痛苦。

我的问题是如何在 CDK 中创建一个支持 s3(中间没有 lambda)的 Rest API,或者至少 apigateway.AwsIntegration 是如何工作的。

我尝试了很多东西,并意识到我是盲编码。我已经在 restApi、lambda、sqs、dynamoDB、s3 之间进行了多次集成,所有这些都非常简单。但是直接把 API Gateway 和 S3 集成在一起,快要哭死了。

我需要一个 restAPI 将请求有效负载直接存储到 S3 存储桶。

这是我已经尝试过的:

向 RestApi 添加策略声明:

const apiResourcePolicy = new iam.PolicyDocument({
        statements: [
          new iam.PolicyStatement({
            effect: iam.Effect.ALLOW,
            actions: ['s3:Put*'],            
            resources: [bucket.bucketName],
            principals: [new ServicePrincipal('apigateway.amazonaws.com')]
          })          
        ]
      });

const api = new apigateway.RestApi(this, "dispatch-api", {
        restApiName: "my api name",
        description: "api description",
        policy: apiResourcePolicy        
      });
Run Code Online (Sandbox Code Playgroud)

我认为这应该足以解决权限问题,但是当我将 AWS 集成添加到 API 时,如下所示:

const getS3Integration = new apigateway.AwsIntegration({
        service: "s3",        
        path: bucket.bucketName,                               
      });

api.root.addMethod("PUT", getS3Integration, {
    requestValidator: requestValidator,
    requestModels: {"application/json": myModel},
  });
Run Code Online (Sandbox Code Playgroud)

我越来越:

1:41:11 PM | CREATE_FAILED        | AWS::ApiGateway::Method           | XXXXXXXXXXXXXXXX
Role ARN must be specified for AWS integrations (Service: AmazonApiGateway; Status Code: 400; Error Code: BadRequestException; Request ID: xxxxxxxxxxxxxxxxxxxxx; Proxy:
null)
Run Code Online (Sandbox Code Playgroud)

我不知道如何指定角色 ARN,我在文档中没有找到。也不知道是否需要向 restAPI 添加策略。我试图在 CDK 中复制这里的示例。

小智 7

以下不是全套,但这应该会给你一些想法。我在SQS上也做过类似的事情,当时我也哭了


    const bucket = new s3.Bucket(this, 'storage');

    const executeRole = new iam.Role(this, "role", {
      assumedBy: new iam.ServicePrincipal('apigateway.amazonaws.com'),
      path: "/service-role/"
    });

    bucket.grantReadWrite(executeRole);

    const api = new apigateway.RestApi(this, 's3api');

    const s3Integration = new apigateway.AwsIntegration({
      service: 's3',
      integrationHttpMethod: "PUT",
      path: "{bucket}",
      options : {
        credentialsRole: executeRole,
        // should have all kind of path mapping..        
      }
    })

    api.root.addResource("{folder}").addMethod("PUT", s3Integration, {
      methodResponses: [
        {
          statusCode: "200"
        }
      ]});
  }
Run Code Online (Sandbox Code Playgroud)