PROVISIONING AN HTTP API + Lambda Function WITH CLOUD FORMATION
Being in an development/engineering team you will be dealing with lot of things that might be building a new functionality or rebuilding an existing feature and when it comes up to scaling up the product as a developer managing and deploying the servers is the tedious task. So now a day most of the developer rely on Iac (Infrastructure as a Code and AWS cloudformation is one of them.
In this Post i will be discussing about Provisioning an HTTP API + Lambda Function using cloudformation. [ CloudFormation is an infrastructure automation platform for AWS that deploys AWS resources in a repeatable, testable and auditable manner ]
PREREQUISITES
- aws account
- aws cli installed on your local machine
CLOUD FORMATION TEMPLATE
Step 1: Create HTTP API Gateway The API Gateway service acts as routing medium to interact with API functions for a client.
Here !GetAtt intrinsic function returns the value of an attribute from a resource in the template.
Resources:
HTTPAPI:
Type: AWS::ApiGatewayV2::Api
Properties:
Description: Example HTTP API
Name: lambda-api
ProtocolType: HTTP
Target: !GetAtt MyLambdaFunction.Arn
Step 2 - creating Lambda Function with message "Hello world"
For Runtime in the place of nodejs12.x you can also use other language like python
The Handler: index.handler is the Lambda function handler method in your function code that processes events. When your function is invoked, Lambda runs the handler method. When the handler exits or returns a response, it becomes available to handle another event.
MyLambdaFunction:
Type: AWS::Lambda::Function
Properties:
Runtime: nodejs12.x
Role: !GetAtt FunctionExecutionRole.Arn
Handler: index.handler
Code:
ZipFile: |
exports.handler = async (event) => {
const response = {
statusCode: 200,
body: JSON.stringify('Hello world!'),
};
return response;
};
Step 3 - Lambda Permission
The below code Lambda Permission enables the lambda to invoke from an api gateway that is defined in the template
APIInvokeLambdaPermission:
Type: AWS::Lambda::Permission
Properties:
FunctionName: !Ref MyLambdaFunction
Action: lambda:InvokeFunction
Principal: apigateway.amazonaws.com
SourceArn: !Sub arn:${AWS::Partition}:execute-api:${AWS::Region}:${AWS::AccountId}:${MyAPI}/$default/$default
Step 4: Creating the Function Execution Role
Description: In the bellow mentioned template to IAM roles are declared so that only an authorised client can request to the function to get it executed.
Principal: Here Principal entity acts as IAM that has an authorisation to make a request for an operation on an AWS resource.
AWS Security Token Service (STS:AssumeRole) AssumeRolePolicy is provided in a role to help enabling trust relationship for other AWS services/AWS accounts to consume this role and gain permissions
FunctionExecutionRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
Service:
- lambda.amazonaws.com
Action:
- 'sts:AssumeRole'
ManagedPolicyArns:
- arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
Outputs:
InvokeURL:
Value: !Sub https://${MyAPI}.execute-api.${AWS::Region}.amazonaws.com
AWSTemplateFormatVersion: '2010-09-09'
Description: |
Example HTTP API, Lambda function, and permissions to invoke the Lambda integration.
Because the template specifies a Target in AWS::ApiGatewayV2::Api, API Gateway uses quick create to create the API.
Quick create produces an HTTP API with an integration, a default catch-all route, and a default stage which is configured to automatically deploy changes.
Resources:
MyAPI:
Type: AWS::ApiGatewayV2::Api
Properties:
Description: Example HTTP API
Name: lambda-api
ProtocolType: HTTP
Target: !GetAtt MyLambdaFunction.Arn
MyLambdaFunction:
Type: AWS::Lambda::Function
Properties:
Runtime: nodejs12.x
Role: !GetAtt FunctionExecutionRole.Arn
Handler: index.handler
Code:
ZipFile: |
exports.handler = async (event) => {
const response = {
statusCode: 200,
body: JSON.stringify('Hello from Lambda!'),
};
return response;
};
APIInvokeLambdaPermission:
Type: AWS::Lambda::Permission
Properties:
FunctionName: !Ref MyLambdaFunction
Action: lambda:InvokeFunction
Principal: apigateway.amazonaws.com
SourceArn: !Sub arn:${AWS::Partition}:execute-api:${AWS::Region}:${AWS::AccountId}:${MyAPI}/$default/$default
FunctionExecutionRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
Service:
- lambda.amazonaws.com
Action:
- 'sts:AssumeRole'
ManagedPolicyArns:
- arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
Outputs:
InvokeURL:
Value: !Sub https://${MyAPI}.execute-api.${AWS::Region}.amazonaws.com
For more templates refer to the github aws docs github.com/awsdocs/amazon-api-gateway-devel..