sheepinwild
sheepinwild

Reputation: 541

How to trigger AWS Lambda from API Gateway with multiple methods?

I'm using cloudformation to define an api gateway that has 4 method defined: GET, POST, PUT and DELETE.

I want to use those 4 method to trigger my lambda. When this template is deployed. The lambda shows with only the DELETE method of the API Gateway.

How can I defined my lambda in cloudformation so that it will take all 4 methods?

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

Upvotes: 4

Views: 5849

Answers (1)

asr9
asr9

Reputation: 2768

The IntegrationHttpMethod is always POST for Lambda proxy integration. See lambda proxy integration - step 5

Important

For Lambda integrations, you must use the HTTP method of POST for the integration request, according to the specification of the Lambda service action for function invocations. The IAM role of apigAwsProxyRole must have policies allowing the apigateway service to invoke Lambda functions. For more information about IAM permissions, see API Gateway Permissions Model for Invoking an API.

So your e.g. GET method integration should look like

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

Upvotes: 9

Related Questions