如何设置 - 方法响应 HTTP - 状态:通过 CFT 在 APIGW 中代理

How to set - Method Response HTTP - Status: Proxy in APIGW via CFT

在过去的几天里,我正在研究云形成模板,它将创建一个 API 网关,它后面有一个 lambda,APIGW 将只有一个 {proxy+} 资源使用任何方法,我想处理后端 lambda 中的所有逻辑。

我能够通过控制台创建相同的内容:

现在我想通过云形成模板复制相同的 我当前的 CloudFormation 模板

AWSTemplateFormatVersion: 2010-09-09
Description: My API Gateway and Lambda function

Parameters:
  apiGatewayName:
    Type: String
    Default: proxy-apigw
  apiGatewayStageName:
    Type: String
    Default: v1
  apiGatewayHTTPMethod:
    Type: String
    Default: ANY
  lambdaFunctionName:
    Type: String
    AllowedPattern: "[a-zA-Z0-9]+[a-zA-Z0-9-]+[a-zA-Z0-9]+"
    Default: proxy-lambda

Resources:
  apiGateway:
    Type: AWS::ApiGateway::RestApi
    Properties:
      Description: Example API Gateway
      EndpointConfiguration:
        Types:
          - REGIONAL
      Name: !Ref apiGatewayName

  apiGatewayLambdaResource:
    Type: 'AWS::ApiGateway::Resource'
    Properties:
      RestApiId: !Ref apiGateway
      PathPart: '{proxy+}'
      ParentId: !GetAtt apiGateway.RootResourceId

  apiGatewayLambdaResourceMethod:
    Type: 'AWS::ApiGateway::Method'
    Properties:
      AuthorizationType: NONE
      RestApiId: !Ref apiGateway
      ResourceId: !Ref apiGatewayLambdaResource
      HttpMethod: ANY
      Integration:
        Type: AWS_PROXY
        IntegrationHttpMethod: POST
        Uri: !Sub 
          - >-
            arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${lambdaArn}/invocations
          - lambdaArn: !GetAtt lambdaFunction.Arn
      MethodResponses:
        - StatusCode: 200
          ResponseModels: { "application/json": "Empty" }

  apiGatewayDeployment:
    Type: AWS::ApiGateway::Deployment
    DependsOn:
      - apiGatewayLambdaResourceMethod
    Properties:
      RestApiId: !Ref apiGateway
      StageName: !Ref apiGatewayStageName

  lambdaFunction:
    Type: AWS::Lambda::Function
    Properties:
      Code:
        ZipFile: |
          exports.handler = async (event) => {
              // TODO implement
              const response = {
                  statusCode: 200,
                  body: JSON.stringify(event),
              };
              return response;
          };
      Description: Example Lambda function
      FunctionName: !Ref lambdaFunctionName
      Handler: index.handler
      Role: !GetAtt lambdaIAMRole.Arn
      Runtime: nodejs12.x

  lambdaApiGatewayInvoke:
    Type: AWS::Lambda::Permission
    Properties:
      Action: lambda:InvokeFunction
      FunctionName: !GetAtt lambdaFunction.Arn
      Principal: apigateway.amazonaws.com
      # note: if route *not* at API Gateway root, `SourceArn` would take the form of:
      #               arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${apiGateway}/${apiGatewayStageName}/${apiGatewayHTTPMethod}/PATH_PART
      SourceArn: !Sub arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${apiGateway}/${apiGatewayStageName}/${apiGatewayHTTPMethod}/

  lambdaIAMRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: 2012-10-17
        Statement:
          - Action:
              - sts:AssumeRole
            Effect: Allow
            Principal:
              Service:
                - lambda.amazonaws.com
      Policies:
        - PolicyDocument:
            Version: 2012-10-17
            Statement:
              - Action:
                  - logs:CreateLogGroup
                  - logs:CreateLogStream
                  - logs:PutLogEvents
                Effect: Allow
                Resource:
                  - !Sub arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/lambda/${lambdaFunctionName}:*
          PolicyName: lambda

  lambdaLogGroup:
    Type: AWS::Logs::LogGroup
    Properties:
      LogGroupName: !Sub /aws/lambda/${lambdaFunctionName}
      RetentionInDays: 90

Outputs:
  apiGatewayInvokeURL:
    Value: !Sub https://${apiGateway}.execute-api.${AWS::Region}.amazonaws.com/${apiGatewayStageName}

  lambdaArn:
    Value: !GetAtt lambdaFunction.Arn

有了这个,我能够在根目录下创建一个 {proxy+} 资源和一个与 /{proxy+} 资源关联的任何方法,但是当我调用 APIGW URL 我是收到内部服务器错误

patelnab@3c22fb980312 ~ % curl --request GET https://nx9gwoz5de.execute-api.us-east-1.amazonaws.com/v1/test/route
{"message": "Internal server error"}%

这是APIGW的样子,是用Cloudformation模板创建的

我能够指出的一个区别是 Method Response,我通过控制台创建的那个有 HTTP Status: Proxy,而通过 CloudFormation 创建的那个没有那个。我尝试在文档中搜索,但找不到太多相关内容。非常感谢对此的任何帮助

您的权限不正确。您缺少 /*:

  lambdaApiGatewayInvoke:
    Type: AWS::Lambda::Permission
    Properties:
      Action: lambda:InvokeFunction
      FunctionName: !GetAtt lambdaFunction.Arn
      Principal: apigateway.amazonaws.com
      # note: if route *not* at API Gateway root, `SourceArn` would take the form of:
      #               arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${apiGateway}/${apiGatewayStageName}/${apiGatewayHTTPMethod}/PATH_PART
      SourceArn: !Sub arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${apiGateway}/${apiGatewayStageName}/${apiGatewayHTTPMethod}/*

如果你想 polulate MethodRequest,你可以这样做:

      Integration:
        Type: AWS_PROXY
        IntegrationHttpMethod: POST
        Uri: !Sub
          - >-
            arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${lambdaArn}/invocations
          - lambdaArn: !GetAtt lambdaFunction.Arn
        IntegrationResponses:
          - ResponseTemplates:
              application/json: ""
            StatusCode: 200
        PassthroughBehavior: WHEN_NO_TEMPLATES