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

Sam*_*ner 12 amazon-web-services aws-cloudformation aws-lambda aws-api-gateway

我一直在网上寻找答案.

基本上,我们使用Swagger来启动一个API,它非常棒并且运行良好,但有一件事不起作用......当我们调用一个端点时,我们得到一个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"
Run Code Online (Sandbox Code Playgroud)

这很棒,但我们正在使用CloudFormation来启动所有内容,我们希望这是自动化的.有没有更简单的方法来解决这个问题?CloudFormation中是否有某些内容可以为我们提供所需的资源政策?

我正在尝试这个问题,但是我今天已经开始工作了几个小时,这对我们的API版本来说有点阻碍,所以任何帮助都会非常感激.:)

kix*_*orz 19

有一个CloudFormation解决这个问题的方法.请参阅以下CloudFormation代码段:

"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" },
            "/*/*/*"
        ] ] }
    }
}
Run Code Online (Sandbox Code Playgroud)

这将API Gateway授予启动Lambda功能的权限.您需要更改的此片段中的变量是Lambda(第4行)和API(第11行).

  • 与“/*/POST/example”相比,执行“/*/*/*”有什么危险吗?从表面上看,我们似乎正在开放该 api 端点调用任何资源路径的权限 (2认同)

小智 6

对于调用权限:

    "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}/*/*/*"
    }
  }
},
Run Code Online (Sandbox Code Playgroud)


rai*_*bba 5

感谢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
Run Code Online (Sandbox Code Playgroud)

使用“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
Run Code Online (Sandbox Code Playgroud)

使用“openapi绑定”

如果您想在 openapi.yaml 中声明绑定,请参阅以下项目(不需要 Lambda/Events)。此方法需要明确的角色才能允许调用。

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"
Run Code Online (Sandbox Code Playgroud)

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]
Run Code Online (Sandbox Code Playgroud)

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