4

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

1 Answer 1

9

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
Sign up to request clarification or add additional context in comments.

1 Comment

Useful answer. It's a good thing that IntegrationHttpMethod always needing to be POST is clearly mentioned here: docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/… Oh, wait...

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.