如何授予 API Gateway 通过 CloudFormation 调用 lambda 函数的权限?

Posted

技术标签:

【中文标题】如何授予 API Gateway 通过 CloudFormation 调用 lambda 函数的权限?【英文标题】:How can I grant permission to API Gateway to invoke lambda functions through CloudFormation? 【发布时间】:2017-02-15 17:53:28 【问题描述】:

我一直在网上寻找答案。

本质上,我们正在使用 Swagger 构建一个 API,它非常棒并且效果很好,但是有一点不起作用......当我们调用 Endpoint 时,我们会收到 500 错误(这不是我们提供的 500 错误是来自 AWS 的错误)。错误状态“由于配置错误导致执行失败:Lambda 函数的权限无效”(https://youtu.be/H4LM_jw5zzs

我已经陷入了许多困境,并找到了答案......它涉及使用 AWS CLI,看起来有点像这样:

aws lambda add-permission \
--function-name FUNCTION_NAME \
--statement-id STATEMENT_ID \
--action lambda:InvokeFunction \
--principal apigateway.amazonaws.com \
--source-arn "arn:aws:execute-api:us-east-1:ACCOUNT_ID:API_ID/*/METHOD/ENDPOINT"

这很好,但我们正在使用 CloudFormation 来启动一切,我们希望这可以自动化。有没有更简单的方法来解决这个问题? CloudFormation 中有什么东西可以为我们提供所需的资源策略吗?

我在这方面遇到了一些困难,但我今天已经为此工作了几个小时,这对我们的 API 版本有点阻碍,因此非常感谢任何帮助。 :)

【问题讨论】:

不管怎样,您也可以通过 AWS 开发工具包做到这一点。我将它用于 Go,所以它在这里:docs.aws.amazon.com/sdk-for-go/api/service/lambda/… ...我看不到有什么方法可以列出现有权限。所以我只是容忍我的部署工具中已经存在的关于它的错误。诡异的。我的意思是我什至没有看到任何关于需要此权限的信息,而且它也不存在于任何导出的 Swagger 中。 【参考方案1】:

有一个CloudFormation 解决这个问题。见下文CloudFormationsn-p:

"Permission": 
    "Type": "AWS::Lambda::Permission",
    "Properties": 
        "FunctionName":  "Fn::GetAtt": [ "Lambda", "Arn" ] ,
        "Action": "lambda:InvokeFunction",
        "Principal": "apigateway.amazonaws.com",
        "SourceArn":  "Fn::Join": [ "", [
            "arn:aws:execute-api:",
             "Ref": "AWS::Region" , ":",
             "Ref": "AWS::AccountId" , ":",
             "Ref": "API" ,
            "/*/*/*"
        ] ] 
    

这将授予API Gateway 启动Lambda 函数的权限。此 sn-p 中您需要更改的变量是 Lambda(第 4 行)和 API(第 11 行)。

【讨论】:

"/*/*/*"/*/POST/example 相比有什么危险吗?从表面上看,我们似乎正在为该 api 端点开放权限以调用任何资源路径 @David 这一切都取决于应用程序 - 您是否需要 API 网关作为过滤器 对于所有 FunctionName 我应该使用哪个? 我需要给我所有的 lambda 权限,所以我应该在 FunctionName 下放什么?? 您可以看到它是一个 ARN。检查它,您可能可以将“*”放在函数名称的末尾。【参考方案2】:

对于调用权限:

    "APIInvokePermission": 
  "Type": "AWS::Lambda::Permission",
  "Properties": 
    "FunctionName": 
      "Ref": "YOUR_LAMBDA_FUNCTION_RESOURCE_NAME"
    ,
    "Action": "lambda:InvokeFunction",
    "Principal": "apigateway.amazonaws.com",
    "SourceArn": 
      "Fn::Sub": "arn:aws:execute-api:$AWS::Region:$AWS::AccountId:$YOUR_REST_API_RESOURCE_NAME/*/*/*"
    
  
,

【讨论】:

我需要给我所有的 lambda 权限,所以我应该在 FunctionName 下放什么??【参考方案3】:

感谢 https://twitter.com/edjgeek 帮助我把这件事弄清楚。

此 GIST 展示了如何使用 AWS::Serverless:Function 和事件来自动生成所需的 AWS::Lambda::Permission 以允许 APIGateway(对于给定路由)调用您的 Lambda:

https://gist.github.com/rainabba/68df1567cbd0c4930d428c8953dc2316

以下两种方法都假设有一个 api,例如(为便于阅读,省略了许多字段):

  MyApi:
    Type: 'AWS::Serverless::Api'
    Properties:
      DefinitionBody:
        Fn::Transform:
          Name: AWS::Include
          Parameters:
            Location: openapi.yaml

使用“SAM 事件”

最相关的部分(我省略了许多必填字段):

  MyLambdaFunction:
    Type: 'AWS::Serverless::Function'
    Properties:
      Events:
        MyRouteEventToProxy:
          Type: Api
          Properties:
            Method: POST
            Path: '/some-route/pathParm'
            RestApiId: !Ref MyApi # ResourceName of AWS::Serverless::Api
            Auth:
              Authorizer: NONE

使用“openapi 绑定”

如果您希望在 openapi.yaml 中声明绑定,请查看以下项目(不需要 Lambda/事件)。这种方法需要一个明确的角色来允许调用。

template.yaml 相关位:

  MyLambdaFunction:
    Type: 'AWS::Serverless::Function'
    Properties:
      # Events: # No need for Events when binding from openapi.yaml
  MyHttpApiRole:
    Type: "AWS::IAM::Role"
    Properties:
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: "Allow"
            Principal:
              Service: "apigateway.amazonaws.com"
            Action: 
              - "sts:AssumeRole"

openapi.yaml 相关位:

paths:
  post:
      x-amazon-apigateway-integration:
        httpMethod: POST
        uri:
          Fn::Sub: "arn:aws:apigateway:$AWS::Region:lambda:path/2015-03-31/functions/$MyLambdaFunction.Arn:live/invocations"
        contentHandling: "CONVERT_TO_TEXT"
        type: aws_proxy
        credentials:
          Fn::GetAtt: [MyHttpApiRole, Arn]

https://github.com/aws-samples/sessions-with-aws-sam/tree/master/http-api-direct-integration

【讨论】:

以上是关于如何授予 API Gateway 通过 CloudFormation 调用 lambda 函数的权限?的主要内容,如果未能解决你的问题,请参考以下文章

无法使用 API Gateway Spring Cloud 调用实际服务

如何在spring cloud gateway中设置超时?

实现Spring Cloud Gateway路由动态加载及持久化

Spring Cloud Gateway 限流操作

Spring Cloud(18)——gateway

基于Spring cloud gateway定制的微服务网关