如何使用 lambda 代理集成来云化 API 网关资源

Posted

技术标签:

【中文标题】如何使用 lambda 代理集成来云化 API 网关资源【英文标题】:How do I cloudform an API gateway resource with a lambda proxy integration 【发布时间】:2017-02-07 21:28:49 【问题描述】:

我一直在尝试研究如何使用 Lambda 代理集成来表达(在 cloudformation 中)具有 Lambda 函数集成类型的 API 网关资源。

这在 AWS 控制台中很容易做到,因为您可以选择一个复选框:

但是AWS::ApiGateway::Method CloudFormation资源中没有对应的字段(应该在Integration property)。

如何在 cloudformation 中进行配置?

【问题讨论】:

我们正在努力让 CloudFormation 更新他们的文档,但如下所述,您将集成类型设置为 AWS_PROXY 并将 HttpMethod 设置为 POST 你可以在这里看到一个工作示例:***.com/questions/48740949/… 对我来说,使用“推荐的”最佳实践云形成路线很难通过控制台轻松完成的事情简直太疯狂了。我想 cloudformer 应该有助于填补这一空白。可惜它已经过时了。 【参考方案1】:

集成类型应设置为AWS_PROXY。下面是来自工作 YAML CloudFormation 模板的方法的示例 sn-p。

ProxyResourceAny:
  Type: AWS::ApiGateway::Method
  Properties:
    AuthorizationType: NONE
    HttpMethod: ANY
    ResourceId:
      Ref: ProxyResource
    RestApiId:
      Ref: API
    Integration:
      Type: AWS_PROXY
      IntegrationHttpMethod: POST
      Uri: !Sub
        - arn:aws:apigateway:$AWS::Region:lambda:path/2015-03-31/functions/$Arn/invocations
        - Arn:
            Fn::GetAtt:
            - RestorerLambda
            - Arn

值得一提的是我是怎么想出来的……

在摸索了一会儿后,我检查了aws apigateway get-method CLI 命令的输出,以了解使用控制台以这种方式配置的方法。这给了我以下 JSON,我意识到复选框可能被编码到类型中。我测试了我的假设并提出了上面的 CloudFormation。


    "apiKeyRequired": false,
    "httpMethod": "ANY",
    "methodIntegration": 
        "integrationResponses": 
            "200": 
                "responseTemplates": 
                    "application/json": null
                ,
                "statusCode": "200"
            
        ,
        "passthroughBehavior": "WHEN_NO_MATCH",
        "cacheKeyParameters": [],
        "uri": "arn:aws:apigateway:eu-west-1:lambda:path/2015-03-31/functions/arn:aws:lambda:eu-west-1:XXXXXXXXX:function:Shildrew-Restorer-Play-Lambda/invocations",
        "httpMethod": "POST",
        "cacheNamespace": "64bl3tgw4g",
        "type": "AWS_PROXY"
    ,
    "requestParameters": ,
    "authorizationType": "NONE"

【讨论】:

【参考方案2】:

我通过简单的更改解决了同样的问题

Integration:
Type: AWS_PROXY

Integration:
Type: AWS

目前云形成文档很少,API 网关 cloudformation 文档与控制台上显示的内容不匹配,这阻碍了任何试图解决问题的人。

希望这会有所帮助!

【讨论】:

不就是这样吗?即从 AWS 到 AWS_PROXY? docs.aws.amazon.com/apigateway/api-reference/resource/…【参考方案3】:

我们遇到了这个确切的问题。我们将 Ansible 用于我们的基础架构。可以应用于 CLI 或 Cloudformation 甚至 SDK

我们的问题的解决方案是确保为您尝试使用的 lambda 的 API Gateway 中的端点谓词以细粒度的方式定义 Lambda 策略。

例如,我们有多个路线。每个路由(或路由集)都需要定义自己的 lambda 策略,以允许 lambda:InvokeFunction。这是在 Ansible 的 Lambda 策略模块中定义的。这样,lambda 触发器就自动启用了。

【讨论】:

【参考方案4】:

有两种方法可以实现:

方法一:通过定义“Lambda”、“API Gateway”、“API Resource”和“API Methods”。使用“API 方法”下的 URI 语句链接 Lambda。

    MyLambdaFunction:
      Type: "AWS::Lambda::Function"
      Properties:
        Description: "Node.js Express REST API"
        FunctionName: "get_list_function" (The name in AWS console)
        Handler: lambda.handler
        Runtime: nodejs12
        MemorySize: 128
        Role: <ROLE ARN>
        Timeout: 60

      apiGateway:
        Type: "AWS::ApiGateway::RestApi"
        Properties:
          Name: "example-api-gw"
          Description: "Example API"
    
      ProxyResource:
        Type: "AWS::ApiGateway::Resource"
        Properties:
          ParentId: !GetAtt apiGateway.RootResourceId
          RestApiId: !Ref apiGateway
          PathPart: 'proxy+' OR "a simple string like "PetStore"
    
      apiGatewayRootMethod:
        Type: "AWS::ApiGateway::Method"
        Properties:
          AuthorizationType: NONE
          HttpMethod: ANY
          Integration:
            IntegrationHttpMethod: POST
            Type: AWS_PROXY
            IntegrationResponses:
              - StatusCode: 200
            Uri: !Sub >-
            arn:aws:apigateway:$AWS::Region:lambda:path/2015-03-31/functions/$MyLambdaFunction.Arn/invocations
          ResourceId: !Ref ProxyResource
          RestApiId: !Ref "apiGateway"

方法 2:定义“API 网关”和“Lambda”。在 Lambda 定义中,调用 API 类型的事件。

 CoreApi:
    Type: 'AWS::Serverless::Api'
    Properties:
      StageName: dev
      Name: SaaSAPI 
      EndpointConfiguration: Regional
      Cors:
        AllowMethods: '''POST, GET, OPTIONS, PATCH, DELETE, PUT'''
        AllowHeaders: '''Content-Type, X-Amz-Date, Authorization, X-Api-Key, x-requested-with'''
        AllowOrigin: '''*'''
        MaxAge: '''600'''

 MyLambdaFunction:
      Type: "AWS::Lambda::Function"
      Properties:
        Description: "Node.js Express REST API"
        FunctionName: "get_list_function"
        Handler: lambda.handler
        Runtime: nodejs12
        MemorySize: 128
        Role: <ROLE ARN>
        Timeout: 60
        Events:
          ProxyResourceA:
            Type: Api
            Properties:
              Path: /Departments
              Method: GET
              RestApiId: !Ref CoreApi

          ProxyResourceB: 
            Type: Api
            Properties:
              Path: /Departments (This becomes the resource in API Gateway)
              Method: POST
              RestApiId: !Ref CoreApi

(您可以使用同一个 lambda 链接多个方法,为每个事件提供唯一名称,例如 ProxyResoruceA 和 ProxyResourceB)

【讨论】:

以上是关于如何使用 lambda 代理集成来云化 API 网关资源的主要内容,如果未能解决你的问题,请参考以下文章

使用代理集成时,API 网关和 Lambda 出现 CORS 错误**仅**

使用代理集成通过 API Gateway 触发 AWS Lambda

API GW Lambda 代理集成 CORS 问题

AWS API Gateway 仅在使用 SAM 时支持 CORS for OPTIONS(没有 Lambda 代理集成)

AWS API Gateway - Lambda 代理(集成请求) - 内部服务器错误

使用代理通过 AWS API Gateway 的 Lambda 错误