首页 > 解决方案 > 如何使用多种方法从 API Gateway 触发 AWS Lambda?

问题描述

我正在使用 cloudformation 定义一个 API 网关,它定义了 4 种方法:GET、POST、PUT 和 DELETE。

我想用这 4 种方法来触发我的 lambda。部署此模板时。lambda 仅显示 API 网关的 DELETE 方法。

如何在 cloudformation 中定义我的 lambda,以便它采用所有 4 种方法?

Resources:
lambdaExecutionRole:
Type: "AWS::IAM::Role"
Properties:
  Path: /
  AssumeRolePolicyDocument:
    Version: 2012-10-17
    Statement:
      - Effect: Allow
        Principal:
          Service:
            - lambda.amazonaws.com
        Action:
          - sts:AssumeRole
  ManagedPolicyArns:
    - !Sub "arn:${AWS::Partition}:iam::aws:policy/service-role/AWSLambdaVPCAccessExecutionRole"

lambdaFunction:
Type: AWS::Lambda::Function
Properties:
  FunctionName: !Ref AWS::StackName
  VpcConfig:
    SubnetIds:
      - {"Fn::ImportValue": !Sub "${networkStackName}-${AWS::Region}-privateSubnetAZ1"}
      - {"Fn::ImportValue": !Sub "${networkStackName}-${AWS::Region}-privateSubnetAZ2"}
    SecurityGroupIds:
      - {"Fn::ImportValue": !Sub "${securityStackName}-${AWS::Region}-sgDNSRestrictedAccess"}
  Runtime: dotnetcore2.1
  Handler: MY::LAMBDA.HANDLER::NAME
  MemorySize: 128
  Role: !GetAtt lambdaExecutionRole.Arn
  Timeout: 30
  Code:
    S3Bucket: bucket-name
    S3Key: bucket-key.zip

lambdaInvokePermission:
Type: "AWS::Lambda::Permission"
Properties:
  FunctionName: !Sub "arn:${AWS::Partition}:lambda:${AWS::Region}:${AWS::AccountId}:function:${AWS::StackName}"
  Action: 'lambda:InvokeFunction'
  Principal: apigateway.amazonaws.com
  SourceArn: !Sub "arn:${AWS::Partition}:execute-api:${AWS::Region}:${AWS::AccountId}:${apiGatewayRestApi}/*"
DependsOn:
  - lambdaFunction

apiGatewayRestApi:
Type: "AWS::ApiGateway::RestApi"
Properties:
  Name: !Ref AWS::StackName
  EndpointConfiguration:
    Types:
      - REGIONAL

apiGatewayResourcePath:
Type: "AWS::ApiGateway::Resource"
Properties:
  RestApiId: !Ref apiGatewayRestApi
  ParentId: !GetAtt 
    - apiGatewayRestApi
    - RootResourceId
  PathPart: !Ref apiGatewayProxyPath
DependsOn:
  - apiGatewayRestApi

apiGatewayPostMethod:
Type: "AWS::ApiGateway::Method"
Properties:
  RestApiId: !Ref apiGatewayRestApi
  ResourceId: !Ref apiGatewayResourcePath
  HttpMethod: POST
  AuthorizationType: NONE
  Integration:
    Type: AWS_PROXY
    IntegrationHttpMethod: POST
    Uri: !Join
      - ":"
      - - "arn"
        - !Ref AWS::Partition
        - "apigateway"
        - !Ref AWS::Region
        - "lambda:path/2015-03-31/functions/arn"
        - !Ref AWS::Partition
        - "lambda"
        - !Ref AWS::Region
        - !Ref AWS::AccountId
        - "function"
        - !Join
          - "/"
          - - !Sub "${AWS::StackName}"
            - "invocations"
DependsOn:
  - apiGatewayResourcePath

apiGatewayGetMethod:
Type: "AWS::ApiGateway::Method"
Properties:
  RestApiId: !Ref apiGatewayRestApi
  ResourceId: !Ref apiGatewayResourcePath
  HttpMethod: GET
  AuthorizationType: NONE
  Integration:
    Type: AWS_PROXY
    IntegrationHttpMethod: GET
    Uri: !Join
      - ":"
      - - "arn"
        - !Ref AWS::Partition
        - "apigateway"
        - !Ref AWS::Region
        - "lambda:path/2015-03-31/functions/arn"
        - !Ref AWS::Partition
        - "lambda"
        - !Ref AWS::Region
        - !Ref AWS::AccountId
        - "function"
        - !Join
          - "/"
          - - !Sub "${AWS::StackName}"
            - "invocations"
DependsOn:
  - apiGatewayResourcePath

apiGatewayPutMethod:
Type: "AWS::ApiGateway::Method"
Properties:
  RestApiId: !Ref apiGatewayRestApi
  ResourceId: !Ref apiGatewayResourcePath
  HttpMethod: PUT
  AuthorizationType: NONE
  Integration:
    Type: AWS_PROXY
    IntegrationHttpMethod: PUT
    Uri: !Join
      - ":"
      - - "arn"
        - !Ref AWS::Partition
        - "apigateway"
        - !Ref AWS::Region
        - "lambda:path/2015-03-31/functions/arn"
        - !Ref AWS::Partition
        - "lambda"
        - !Ref AWS::Region
        - !Ref AWS::AccountId
        - "function"
        - !Join
          - "/"
          - - !Sub "${AWS::StackName}"
            - "invocations"
DependsOn:
  - apiGatewayResourcePath

apiGatewayDeleteMethod:
Type: "AWS::ApiGateway::Method"
Properties:
  RestApiId: !Ref apiGatewayRestApi
  ResourceId: !Ref apiGatewayResourcePath
  HttpMethod: DELETE
  AuthorizationType: NONE
  Integration:
    Type: AWS_PROXY
    IntegrationHttpMethod: DELETE
    Uri: !Join
      - ":"
      - - "arn"
        - !Ref AWS::Partition
        - "apigateway"
        - !Ref AWS::Region
        - "lambda:path/2015-03-31/functions/arn"
        - !Ref AWS::Partition
        - "lambda"
        - !Ref AWS::Region
        - !Ref AWS::AccountId
        - "function"
        - !Join
          - "/"
          - - !Sub "${AWS::StackName}"
            - "invocations"
DependsOn:
  - apiGatewayResourcePath

apiGatewayDeployment:
Type: "AWS::ApiGateway::Deployment"
Properties:
  RestApiId: !Ref apiGatewayRestApi
DependsOn:
  - apiGatewayPostMethod
  - apiGatewayGetMethod
  - apiGatewayDeleteMethod
  - apiGatewayPutMethod

apiGatewayStage:
Type: "AWS::ApiGateway::Stage"
Properties:
  StageName: app
  RestApiId: !Ref apiGatewayRestApi
  DeploymentId: !Ref apiGatewayDeployment
  MethodSettings:
    - ResourcePath: !Sub "/${apiGatewayProxyPath}"
      HttpMethod: POST
      MetricsEnabled: true
      LoggingLevel: INFO
    - ResourcePath: !Sub "/${apiGatewayProxyPath}"
      HttpMethod: GET
      MetricsEnabled: true
      LoggingLevel: INFO
    - ResourcePath: !Sub "/${apiGatewayProxyPath}"
      HttpMethod: PUT
      MetricsEnabled: true
      LoggingLevel: INFO
    - ResourcePath: !Sub "/${apiGatewayProxyPath}"
      HttpMethod: DELETE
      MetricsEnabled: true
      LoggingLevel: INFO
DependsOn:
  - apiGatewayDeployment

标签: aws-lambdaamazon-cloudformationaws-api-gateway

解决方案


IntegrationHttpMethod始终POST用于Lambda proxy集成。请参阅lambda 代理集成 - 步骤 5

重要的

对于 Lambda 集成,您必须根据函数调用的 Lambda 服务操作规范,对集成请求使用 POST 的 HTTP 方法。apigAwsProxyRole 的 IAM 角色必须具有允许 apigateway 服务调用 Lambda 函数的策略。有关 IAM 权限的更多信息,请参阅用于调用 API 的 API Gateway 权限模型。

所以你的例如 GET 方法集成应该看起来像

apiGatewayGetMethod:
Type: "AWS::ApiGateway::Method"
Properties:
  RestApiId: !Ref apiGatewayRestApi
  ResourceId: !Ref apiGatewayResourcePath
  HttpMethod: GET
  AuthorizationType: NONE
  Integration:
    Type: AWS_PROXY
    IntegrationHttpMethod: POST
    Uri: !Join
      - ":"
      - - "arn"
        - !Ref AWS::Partition
        - "apigateway"
        - !Ref AWS::Region
        - "lambda:path/2015-03-31/functions/arn"
        - !Ref AWS::Partition
        - "lambda"
        - !Ref AWS::Region
        - !Ref AWS::AccountId
        - "function"
        - !Join
          - "/"
          - - !Sub "${AWS::StackName}"
            - "invocations"
DependsOn:
  - apiGatewayResourcePath

推荐阅读