How to build a serverless REST API using CloudFormation

What are AWS Lambda and API Gateway

AWS Lambda lets you run your code without provisioning or managing any servers. This gives you a completely serverless architecture with little to no effort on maintenance.

Amazon API Gateway is a fully managed service for managing your APIs. In order for your Lambda to run, it will need a trigger event. AWS allows you to attach multiple different event sources, like SQS, DynamoDB Streams, but in this article, I will focus on API Gateway.

By setting API Gateway as the event source, Lambda can receive your API input and send the output back to API Gateway.

What is AWS CloudFormation

AWS CloudFormation allows you to create your infrastructure as code. And by deploying your CloudFormation script, AWS will automatically provision all resources specified. This script will serve as the single source of truth for your cloud environment.

Let’s Get Started

LambdaFunction creates a Lambda function called SampleLambda with a memory size of 128 mb and a timeout of 10 seconds.

LambdaFunction:
Type: AWS::Lambda::Function
Properties:
Code:
S3Bucket: <BUCKET_NAME>
S3Key: <BUCKET_KEY>
Description: This is a sample Lambda
FunctionName: SampleLambda
Handler: main
MemorySize: 128
Role: !GetAtt LambdaFunctionRole.Arn
Runtime: go1.x
Timeout: 10

LambdaFunctionRole creates a Lambda IAM role called SampleLambdaRole. This gives your Lambda permissions to perform certain actions. The role below allows your Lambda to perform X-Ray PutTraceSegments and PutTelemetryRecords.

LambdaFunctionRole:
Type: AWS::IAM::Role
Properties:
RoleName: SampleLambdaRole
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action: sts:AssumeRole
Principal:
Service:
- lambda.amazonaws.com
Path: '/'
ManagedPolicyArns:
- arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
- arn:aws:iam::aws:policy/AWSXRayDaemonWriteAccess

Api creates an API Gateway from a Swagger/OpenAPI file. By doing so, you can document your API at the same time. One limitation is that you will need to upload your Swagger file to S3 before deploying CloudFormation.

ApiAccount allows you to attach a CloudWatch role to your API Gateway.

ApiStage creates an API stage and ApiDeployment deploys your API stage.

Api:
Type: AWS::ApiGateway::RestApi
Properties:
Name: SampleAPIGateway
Description: Sample API Gateway
EndpointConfiguration:
Types:
- REGIONAL
Body:
Fn::Transform:
Name: AWS::Include
Parameters:
Location: !Sub s3://swagger.yaml
ApiAccount:
Type: AWS::ApiGateway::Account
Properties:
CloudWatchRoleArn: !GetAtt CloudWatchRole.Arn
CloudWatchRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action: sts:AssumeRole
Principal:
Service:
- apigateway.amazonaws.com
Path: '/'
ManagedPolicyArns:
- 'arn:aws:iam::aws:policy/service-role/AmazonAPIGatewayPushToCloudWatchLogs'
ApiStage:
Type: 'AWS::ApiGateway::Stage'
DependsOn:
- ApiAccount
Properties:
DeploymentId: !Ref ApiDeployment
MethodSettings:
- DataTraceEnabled: true
HttpMethod: '*'
LoggingLevel: INFO
ResourcePath: /*
RestApiId: !Ref Api
StageName: !Ref StageParameter
ApiDeployment:
Type: AWS::ApiGateway::Deployment
Properties:
RestApiId: !Ref Api

Congratulations! You now have a CloudFormation script ready to deploy.

But before you can deploy, you will need to run the package command. This will transform your Swagger file and add it to packaged-template.yaml.

$ aws cloudformation package --template-file template.yaml --s3-prefix $BUCKET_KEY --s3-bucket $BUCKET_NAME --output-template-file packaged-template.yaml

Next, run the deploy command to deploy the Lambda and API Gateway to your AWS account.

$ aws cloudformation deploy --template-file packaged-template.yaml --stack-name sample-stack --capabilities CAPABILITY_NAMED_IAM

Hope this article helped build a microservice with AWS Lambda and API Gateway using CloudFormation.

Give this article a clap if it helped you. ☺

Do follow me if you have not already done so!

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store