Hey, Welcome!
In this post I am going to share how you can quickly setup a cloudformation stack with HTTP API Gateway proxying requests to serverless lambda function.
You can read in my previous post on setting up an HTTP API gateway with custom domain.
To make it simpler, I will break it down into multiple steps.
If you are just interested in the yaml
template simply scroll down to the end.
Step 1: Create serverless lambda function
DemoFunction:
Type: AWS::Serverless::Function
Properties:
Handler: index.handler
Runtime: "nodejs12.x"
InlineCode: |
exports.handler = function(event, context, callback) {
console.log(event);
const response = {
statusCode: 200,
body: JSON.stringify('Hello Node rule 1')
};
callback(null, response);
};
The above code creates serverless lambda function.
This lambda function basically uses
-
nodejs12.x
as runtime - inline source code which can be
CodeUri
property that reference the source code from file
Step 2: Enable lambda invoke permission
DemoLambdaInvokePermission:
Type: AWS::Lambda::Permission
Properties:
FunctionName: !Ref DemoFunction
Action: "lambda:InvokeFunction"
Principal: apigateway.amazonaws.com
The above code enables the lambda invoke from an api gateway You can read more about the lambda invoke permission.
Step 3: Create lambda proxy integration
DemoIntegration:
Type: AWS::ApiGatewayV2::Integration
Properties:
ApiId: !Ref DemoHttpApi
Description: Lambda proxy integration
IntegrationType: AWS_PROXY
IntegrationMethod: GET
PayloadFormatVersion: "2.0"
IntegrationUri: !Sub 'arn:${AWS::Partition}:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${DemoFunction.Arn}/invocations'
The above code integrates the lambda function with an HTTP api gateway.
You can read more about the lambda proxy integration here
Step 4: Create api route
DemoApiRoute:
Type: AWS::ApiGatewayV2::Route
Properties:
ApiId: !Ref DemoHttpApi
RouteKey: "GET /demo"
AuthorizationType: AWS_IAM
Target: !Join
- /
- - integrations
- !Ref DemoIntegration
The above code creates an api route with requests targeted to the lambda proxy integration.
I have configured authorization type as AWS_IAM
which means the calling client (IAM role) must have permission to execute API gateway.
I use this API gateway for internal service communication where the calling site is another lambda function.
It implies that my lambda function X
requests data from api gateway which proxies the requests to lambda function Y
and this request is authenticated using AWS_IAM
mechanism.
Step 5: Call site lambda function
DemoCallFunction:
Type: AWS::Serverless::Function
Properties:
Handler: index.handler
Runtime: nodejs12.x
CodeUri: dist/lambda/demoCall/
Policies:
- AmazonAPIGatewayInvokeFullAccess
That is all you need to integrate lambda function with an HTTP api gateway.
You can use the below template to create cloudformation stack with all the above resources we talked about.
AWSTemplateFormatVersion: "2010-09-09"
Transform: AWS::Serverless-2016-10-31
Description: Lambda with HTTP API gateway demo stack
Resources:
##########################################
## create your API gateway resources ##
## as described in my previous post ##
##########################################
DemoFunction:
Type: AWS::Serverless::Function
Properties:
Handler: index.handler
Runtime: "nodejs12.x"
InlineCode: |
exports.handler = function(event, context, callback) {
console.log(event);
const response = {
statusCode: 200,
body: JSON.stringify('Hello Node rule 1')
};
callback(null, response);
};
DemoLambdaInvokePermission:
Type: AWS::Lambda::Permission
Properties:
FunctionName: !Ref DemoFunction
Action: "lambda:InvokeFunction"
Principal: apigateway.amazonaws.com
DemoIntegration:
Type: AWS::ApiGatewayV2::Integration
Properties:
ApiId: !Ref DemoHttpApi
Description: Lambda proxy integration
IntegrationType: AWS_PROXY
IntegrationMethod: POST
PayloadFormatVersion: "2.0"
IntegrationUri: !Sub 'arn:${AWS::Partition}:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${DemoFunction.Arn}/invocations'
DemoApiRoute:
Type: AWS::ApiGatewayV2::Route
Properties:
ApiId: !Ref DemoHttpApi
RouteKey: "GET /demo"
AuthorizationType: AWS_IAM
Target: !Join
- /
- - integrations
- !Ref DemoIntegration
In my next post, I will be sharing how we can connect a lambda function to an application load balancer.
Top comments (2)
Very useful! Thanks for writing this.
One minor change that can simplify the template by a few characters is instead of
IntegrationUri: !Sub 'arn:${AWS::Partition}:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${DemoFunction.Arn}/invocations'
, I tested we can also useIntegrationUri: !GetAtt DemoFunction.Arn
, which still works.thank you so much ! this article is very helpful.