首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在CDK中将API网关与s3集成

如何在CDK中将API网关与s3集成
EN

Stack Overflow用户
提问于 2020-09-11 17:51:57
回答 3查看 4K关注 0票数 11

在控制台https://docs.aws.amazon.com/apigateway/latest/developerguide/integrating-api-with-aws-services-s3.html中,docs非常清楚地做了这件事,但是在CDK中复制确实很痛苦。

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

我尝试过很多事情,却意识到自己是在盲目地编码。我已经在restApi、lambda、sqs、dynamoDB、s3之间进行了多次集成,它们都非常容易。但是直接将API与S3集成在一起会让我大哭一场。

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

这就是我已经尝试过的:

在RestApi中添加策略:

代码语言:javascript
复制
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        
      });

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

代码语言:javascript
复制
const getS3Integration = new apigateway.AwsIntegration({
        service: "s3",        
        path: bucket.bucketName,                               
      });

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

我得到了:

代码语言:javascript
复制
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)

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

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2020-09-14 11:19:30

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

代码语言:javascript
复制
    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"
        }
      ]});
  }
票数 18
EN

Stack Overflow用户

发布于 2020-09-13 21:20:36

在您链接的文档(https://docs.aws.amazon.com/apigateway/latest/developerguide/integrating-api-with-aws-services-s3.html)中的“设置API调用Amazon操作的IAM权限”一节中,您需要使用的策略与您所编码的完全不同。

您的策略(如果应用于桶)会说:如果请求来自服务"api网关“,则允许put:*操作。此方法适用于其他用例。

根据文件,你需要:

  • 创建一个角色
  • 角色应该包含策略:
    1. 允许的操作(在您的情况下是put:*)
    2. 允许api网关切换到角色。

  • 使用apigateway.RestApi中的角色

政策(1)应该是显而易见的,文件中给出的第(2)项是:

代码语言:javascript
复制
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "",
      "Effect": "Allow",
      "Principal": {
        "Service": "apigateway.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
} 
票数 1
EN

Stack Overflow用户

发布于 2020-09-14 01:02:18

从您的描述来看,在我看来,您不是,没有为您的集成提供IAM角色。您只为政策提供了一个RestApi,这是一个用于API的基于资源的策略。换句话说,它不适用于您的集成,而是指定谁可以执行您的API。通常,如果要使API公开,则不使用它。

对于AWS集成,您应该使用S3 permissions使用IntegrationOptions提供IAM角色。具体来说,通过credentials选项:

API网关承担的IAM角色。

CDK映射到的CloudFormation文档具有集成Credentials上的更多细节

集成所需的凭据。若要指定API网关所承担的AWS标识和访问管理(IAM)角色,请指定角色的(ARN)。要要求从请求中传递调用者的身份,请指定arn:aws:iam::user/。若要对AWS Lambda (Lambda)函数使用基于资源的权限,请不要指定此属性。使用AWS::Lambda::权限资源允许API网关调用该函数。有关更多信息,请参见AWS Lambda Developer指南中允许Amazon网关调用Lambda函数。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/63852022

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档