AWS Serverless: Create an Application with SAM

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

  1. Account AWS.
  2. IAM User with granted permission to Lambda and API Gateway.
  3. aws-sam-cli installation.

Architecture

Picture 1. Simple Architecture SAM (source: dev.to)

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.

Picture 2. sample images

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.

Picture 3. Events

To access the API Endpoint, you can check it on Triggers.

Picture 4. Triggers

Finally, we can try to access the endpoint.

curl https://nxicn1na0j.execute-api.ap-southeast-1.amazonaws.com or access from Web/Postman.

Picture 5. Result

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

  1. Amazon. AWS Serverless Application Model. https://aws.amazon.com/serverless/sam/
  2. Dev.to. A First Look at AWS SAM. https://dev.to/ajcwebdev/a-first-look-at-aws-sam-478c
  3. Putra, Anton. 2021. How to create Lambda Container Images. https://www.youtube.com/watch?v=gPIpsfYGBZg

Published by boy.suganda

My name is Boy Suganda Sinaga. I worked as Site Reliability Engineer (SRE) at Shipper Indonesia. I'm still developing my skill, both hard-skill and soft-skill. Let's work together, to bring better future for others.

Leave a Reply

Your email address will not be published. Required fields are marked *