Kai Kiat Poh.

Deploying lambda using Serverless

Tasmania view

Hello! This post will be about deploying AWS lambda using serverless. AWS Lambda is a serverless computing technology providing several key benefits such as

  1. No server management
  2. Scaling
  3. Do not have to pay for idle time
  4. Easy intergration with other services

Firstly, create a brand new nest.js project and create lambda.ts in the src folder. This is to wrap the endpoints with a lambda handler

// lambda.ts
let cachedServer;

export const handler = async (event, context) => {
  if (!cachedServer) {
    const nestApp = await NestFactory.create(AppModule);
    await nestApp.init();
    cachedServer = serverlessExpress({
      app: nestApp.getHttpAdapter().getInstance(),
    });
  }

  return cachedServer(event, context);
};

Next create serverless.yaml in the root folder.

service: sample-api
frameworkVersion: '3'
plugins:
  - serverless-offline
  - serverless-dynamodb-local
provider:
  name: aws
  runtime: nodejs18.x
  region: ap-southeast-1
  environment:
    IS_DEVELOPMENT: true
  iam:
    role:
      statements:
      - Effect: Allow
        Action:
          - dynamodb:DescribeTable
          - dynamodb:Query
          - dynamodb:Scan
          - dynamodb:GetItem
          - dynamodb:PutItem
          - dynamodb:DeleteItem
        Resource: "arn:aws:dynamodb:ap-southeast-1:*:table/PostTable"
functions:
  api:
    handler: dist/lambda.handler
    events:
      - http:
          method: GET
          path: /
      - http:
          method: GET
          path: /healthz
      - http:
          method: GET
          path: /blogs
      - http:
          method: GET
          path: /blog/{id} 
      - http:
          method: DELETE
          path: /blog/{id} 
      - http:
          method: POST
          path: /blog
resources:
  Resources:
    PostTable:
      Type: AWS::DynamoDB::Table
      Properties:
        TableName: PostTable
        AttributeDefinitions:
          - AttributeName: postID
            AttributeType: S
        KeySchema:
          - AttributeName: postID
            KeyType: HASH
        ProvisionedThroughput:
          ReadCapacityUnits: 1
          WriteCapacityUnits: 1

There are a few plugins that we need to install

  • serverless-offline: Allow to test in localhost
  • serverless-dynamodb-local: Allow us to run dynamodb locally to test

To interact with dynamodb, use the latest AWS Javascript V3 SDK. Below is an example of retrieving an entry from dynamodb using the hash key, postID.

async getBlogPost(id: string): Promise<any> {
    try {
      const response = await dynamoDB.send(
        new GetItemCommand({
          TableName: tableName,
          Key: {
            postID: { S: id },
          },
        }),
      );
      return response
    } catch (e) {
      throw new InternalServerErrorException(e);
    }
  }

Lastly create a CI pipeline, either using GitHub Action or any platform of your choice. There are 2 commands to run namely, first to build the project, then to deploy it to AWS lambda

  1. yarn build
  2. serverless deploy

That's all for now. There's too much code here :/

See you in the next one !