SAM stands for Serverless Application Model. It can be helpful for the developer who wants to reduce manual stuff when creating and configuring serverless resources. It is an open-source framework for building serverless applications.
For the benefits and more detailed information, click this documentation.
Short Description
Traditionally, when we required resources like Lambda, API Gateway, and EventBridge, we will use the console to create lambda and Add Trigger API Gateway and EventBridge sequentially, taking longer time, and sometimes the result is not as expected. Also, when we didn’t need the resource related the project (Lambda, API Gateway, …), we still did it manually and potentially leave trash on our infrastructure.
In this tutorial, we will find out the way to make it better.
Prerequisites
- Account AWS.
- IAM User with granted permission to Lambda and API Gateway.
- aws-sam-cli installation.
Architecture
In Picture 1, you can see that from SAM template will create stack on Cloudformation, which going to deploy resources based on our template.
Implementation
Creating Image
In the first step of our implementation, we need a container image. We will learn to create a simple image for our application.
One of the supported runtimes is Node.js, and let’s try.
For the simple hello application, we will add this script with filename hellojs.js
.
// hello.js
const faker = require('faker');
exports.handler = async (event) => {
const country = faker.address.country();
const response = {
statusCode: 200,
body: `Hello Boy from ${country}`
};
return response;
}
faker is dependency on java and has massive amounts of fake (but realistic) data for testing and development. We will use the address feature in this code. In this code, we just want to print Hello Boy from random multiple countries.
The second file is Dockerfile
. It’s required to build our image with additional commands as needed.
// Dockerfile
FROM public.ecr.aws/lambda/nodejs:14
COPY hellojs.js package*.json /var/task/
RUN npm install --save-dev faker@5.5.3
RUN npm install
CMD [ "hellojs.handler" ]
we will need to install dependency faker
on our image to support our application. On CMD line, you’ll set the call handler handler
from hellojs
‘s file. We use public.ecr.aws/lambda/nodejs:14
as base image for lambda NodeJS 14.
The next step is building the image. We can create image by execute this command.
$ docker build -t 614808202281.dkr.ecr.ap-southeast-1.amazonaws.com/sample:hello-js .
For M1 user, i suggest to add --platform=linux/amd64
to prevent error like error: fork/exec /lambda-entrypoint.sh: exec format error ...
Why i set the image name as 614808202281.dkr.ecr.ap-southeast-1.amazonaws.com/sample
? Because, we need to push it first to ECR repository for Deployment with Container Images.
After the build image had been done, we push the image by…
$ docker push 614808202281.dkr.ecr.ap-southeast-1.amazonaws.com/sample:hello-js
Now we have it.
The next thing is creating SAM template as deployment part. Set the name as template.yaml
.
AWSTemplateFormatVersion: "2010-09-09"
Transform: AWS::Serverless-2016-10-31
Description: >
hellojssvc
Simple service Hello with NodeJS.
Resources:
hellojssvc:
Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction
Properties:
ImageUri: 614808202281.dkr.ecr.ap-southeast-1.amazonaws.com/sample:hello-js
PackageType: Image
Architectures:
- x86_64
Events:
ApiEvent:
Type: HttpApi
Properties:
Path: /{proxy+}
Method: ANY
ApiId:
Ref: hellojssvcHTTPApiGateway
Metadata:
DockerTag: v1.0.0
DockerContext: .
DockerFile: ./Dockerfile
hellojssvcHTTPApiGateway:
Type: AWS::Serverless::HttpApi
RouteSettings: "ANY /{proxy+}"
Properties:
Description: "HTTP Api Gateway, Created using AWS SAM."
In this template, we will create Lambda Function and API Gateway with additional resources to support the process.
Before doing it on AWS, please try it first on local.
$ docker run -p 9000:8080 614808202281.dkr.ecr.ap-southeast-1.amazonaws.com/sample:hello-js
$ curl -XPOST "http://localhost:9000/2015-03-31/functions/function/invocations" -d '{}'
It will return {"statusCode":200,"body":"Hello Boy from Martinique"}
.
Deployment on AWS
Let’s go for it, deployment time on AWS!
Related sam command, it’s better to explore documentation.
$ sam deploy --template-file template.yaml --capabilities CAPABILITY_IAM --stack-name demo-hellojs --region ap-southeast-1 --image-repository 614808202281.dkr.ecr.ap-southeast-1.amazonaws.com/sample:hello-js
As a note, your current working directory should be the same with template.yaml
‘s location. stack-name is mandatory and required for Cloudformation stack name. If you’re using non-default profile on ~/.aws/credentials
, add --profile $profile_name
.
After executing previous command, you can track the events on the terminal.
To access the API Endpoint, you can check it on Triggers.
Finally, we can try to access the endpoint.
curl https://nxicn1na0j.execute-api.ap-southeast-1.amazonaws.com
or access from Web/Postman.
We are getting Hello Boy from Cuba printed right now. Congratulations!
To remove the stacks, you can execute it by…
$ sam delete --stack-name demo-hellojs
And return Deleted successfully
…
References
- Amazon. AWS Serverless Application Model. https://aws.amazon.com/serverless/sam/
- Dev.to. A First Look at AWS SAM. https://dev.to/ajcwebdev/a-first-look-at-aws-sam-478c
- Putra, Anton. 2021. How to create Lambda Container Images. https://www.youtube.com/watch?v=gPIpsfYGBZg