SQS Invoke Lambda Function to DynamoDB

SQSInvokeLambda.png

As I prepare for the AWS Certified Developer exam I've been building out a reference of SAM templates and Lambda functions to reinforce what I've learned. I'm going to be sharing these as I complete them, hopefully, they'll be a resource for someone else. Feel free to fork the repository and submit any updates, fixes or recommendations.

The repository is here: https://github.com/kcearns/lambda-sam-templates

SQS/Lambda -> DynamoDB

The first template I've put together is a simple event-based workflow. An SQS event triggers a Lambda function when a message is added to the queue. That message is logged to Cloudwatch and inserted into a DynamoDB table by the function.

If you don't have the SAM CLI installed please visit this link and install it.

The SAM template is as follows:

AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: Example of processing messages on an SQS queue with Lambda
Resources:
  MySQSQueueFunction:
    Type: AWS::Serverless::Function
    Properties:
      CodeUri: src/
      Handler: index.handler
      Runtime: nodejs12.x
      Timeout: 30
      Environment:
        Variables:
          DB_NAME: !Ref MySqsQueueDynamoDB
      Events:
        MySQSEvent:
          Type: SQS
          Properties:
            Queue: !GetAtt MySqsQueue.Arn
      Policies:
        - AWSLambdaSQSQueueExecutionRole
        - AmazonDynamoDBFullAccess
  MySqsQueue:
    Type: AWS::SQS::Queue
  MySqsQueueDynamoDB:
    Type: AWS::Serverless::SimpleTable
    Properties:
      TableName: MySqsQueueDynamoDB
      PrimaryKey:
        Name: id
        Type: String
      ProvisionedThroughput:
        ReadCapacityUnits: 1
        WriteCapacityUnits: 1

The first resource is the Lambda function "MySQSQueueFunction". It sets the DB_NAME environment variable referencing the name of the DynamoDB table:

DB_NAME: !Ref MySqsQueueDynamoDB

It creates an SQS event and sets the queue as the MySqsQueue ARN (Amazon Resouce Name):

  Events:
    MySQSEvent:
      Type: SQS
      Properties:
        Queue: !GetAtt MySqsQueue.Arn

The SQS queue is created with the "MySqsQueue" resource:

  MySqsQueue:
    Type: AWS::SQS::Queue

The DynamoDB table is created with the resource named MySqsQueueDynamoDB:

  MySqsQueueDynamoDB:
    Type: AWS::Serverless::SimpleTable
    Properties:
      TableName: MySqsQueueDynamoDB
      PrimaryKey:
        Name: id
        Type: String
      ProvisionedThroughput:
        ReadCapacityUnits: 1
        WriteCapacityUnits: 1

There isn't a lot to the template and the permissions could be modified to limit access to the table but this exercise was to create a simple SQS Lambda function trigger.

The Lambda function code is below:

const AWS = require("aws-sdk")
const uuid = require("uuid")

const DynamoDB = new AWS.DynamoDB.DocumentClient({ region: "us-east-1" })

exports.handler = async (event) => {
  const { body } = event.Records[0]
  let params = {
    TableName: process.env.DB_NAME,
    Item: {
      id: uuid.v4(),
      msg: body,
    },
  }
  try {
    await DynamoDB.put(params).promise()
    console.log({"success": true, "msg": params})
  } catch (err) {
    console.log({"success": false, "msg": err.message})
  }
}

To create the AWS resources using the template run sam build. Once that completes run sam deploy --guided.