How to Trigger an AWS Lambda from DynamoDB

thealexkates

Alex Kates

Posted on May 14, 2021

How to Trigger an AWS Lambda from DynamoDB

In this post we are going to use the AWS CDK to build an AWS Lambda Function that triggers from DynamoDB Stream Events.

All of the code can be found in this repository.

Setup

We need to run a few commands to setup our CDK app.

mkdir how-to-trigger-lambda-from-ddb-stream
cd how-to-trigger-lambda-from-ddb-stream
npx cdk init app --language typescript
Enter fullscreen mode Exit fullscreen mode

This should give you the following directory structure.

Alt Text

Also make sure you have your AWS CLI configured. For more information follow the AWS CLI quickstart guide.

DynamoDB

Install the DynamoDB CDK package.

npm i @aws-cdk/aws-dynamodb
Enter fullscreen mode Exit fullscreen mode

Open lib/how-to-trigger-lambda-from-ddb-stream-stack.ts, add a new DynamoDB table and deploy.

import * as cdk from '@aws-cdk/core';
import * as dynamodb from '@aws-cdk/aws-dynamodb';

export class HowToTriggerLambdaFromDdbStreamStack extends cdk.Stack {
  constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    const table = new dynamodb.Table(this, 'Table', {
      billingMode: dynamodb.BillingMode.PAY_PER_REQUEST,
      partitionKey: { name: 'id', type: dynamodb.AttributeType.STRING },
      stream: dynamodb.StreamViewType.NEW_AND_OLD_IMAGES,
      tableName: 'Table',
    });
  }
}

Enter fullscreen mode Exit fullscreen mode
npm run cdk deploy
Enter fullscreen mode Exit fullscreen mode

Lambda

Install the Lambda CDK package.

npm i @aws-cdk/aws-lambda
Enter fullscreen mode Exit fullscreen mode

Deploying Lambda functions requires bootstrapping your CDK app which gives us an S3 bucket where our Lambda's source code will live.

npm run cdk bootstrap
Enter fullscreen mode Exit fullscreen mode

Create src/index.js and paste the following code

exports.handler = async (event) => {
    event.Records.forEach((record) => {
        console.log('Event Id: %s', record.eventID);
        console.log('Event Id: %s', record.eventName);
        console.log('DynamoDB Record: %j', record.dynamodb);
    });
};
Enter fullscreen mode Exit fullscreen mode

Open lib/how-to-trigger-lambda-from-ddb-stream-stack.ts, add a new Lambda function and deploy.

import * as cdk from '@aws-cdk/core';
import * as dynamodb from '@aws-cdk/aws-dynamodb';
import * as lambda from '@aws-cdk/aws-lambda';

export class HowToTriggerLambdaFromDdbStreamStack extends cdk.Stack {
  constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    const table = new dynamodb.Table(this, 'Table', {
      billingMode: dynamodb.BillingMode.PAY_PER_REQUEST,
      partitionKey: { name: 'id', type: dynamodb.AttributeType.STRING },
      tableName: 'Table',
    });

    const lambdaFunction = new lambda.Function(this, 'Function', {
      code: lambda.Code.fromAsset('src'),
      handler: 'index.handler',
      functionName: 'TableStreamHandler',
      runtime: lambda.Runtime.NODEJS_12_X,
    });
  }
}

Enter fullscreen mode Exit fullscreen mode
npm run cdk deploy
Enter fullscreen mode Exit fullscreen mode

Event Source

Install the Lambda Event Sources CDK package.

npm i @aws-cdk/aws-lambda-event-sources
Enter fullscreen mode Exit fullscreen mode

Open lib/how-to-trigger-lambda-from-ddb-stream-stack.ts, add a new DynamoEventSource to the Lambda Function.

import * as cdk from '@aws-cdk/core';
import * as dynamodb from '@aws-cdk/aws-dynamodb';
import * as lambda from '@aws-cdk/aws-lambda';
import { DynamoEventSource } from '@aws-cdk/aws-lambda-event-sources';

export class HowToTriggerLambdaFromDdbStreamStack extends cdk.Stack {
  constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    const table = new dynamodb.Table(this, 'Table', {
      billingMode: dynamodb.BillingMode.PAY_PER_REQUEST,
      partitionKey: { name: 'id', type: dynamodb.AttributeType.STRING },
      stream: dynamodb.StreamViewType.NEW_AND_OLD_IMAGES,
      tableName: 'Table',
    });

    const lambdaFunction = new lambda.Function(this, 'Function', {
      code: lambda.Code.fromAsset('src'),
      handler: 'index.handler',
      functionName: 'TableStreamHandler',
      runtime: lambda.Runtime.NODEJS_12_X,
    });

    lambdaFunction.addEventSource(new DynamoEventSource(table, {
      startingPosition: lambda.StartingPosition.LATEST,
    }));
  }
}

Enter fullscreen mode Exit fullscreen mode
npm run cdk deploy
Enter fullscreen mode Exit fullscreen mode

Testing

Using the AWS CLI, insert a new item into the DynamoDB table.

aws dynamodb put-item \
    --table-name Table \
    --item '{
        "id": {"S": "test123"}
      }'
Enter fullscreen mode Exit fullscreen mode

Verify that the Lambda executed by looking in CloudWatch. Find the LogGroup named /aws/lambda/TableStreamHandler and open up the latest LogStream. You should see some log messages that look similar to this.

2021-05-14T19:08:55.487Z    ffba16f2-846b-4c6e-9ff5-189c3293116e    INFO    Event Id: e6db4f872fd1997f0f459bcebb8163e8
Enter fullscreen mode Exit fullscreen mode
2021-05-14T19:08:55.527Z    ffba16f2-846b-4c6e-9ff5-189c3293116e    INFO    Event Id: INSERT

Enter fullscreen mode Exit fullscreen mode
2021-05-14T19:08:55.527Z    ffba16f2-846b-4c6e-9ff5-189c3293116e    INFO    DynamoDB Record: {
    "ApproximateCreationDateTime": 1621019335,
    "Keys": {
        "id": {
            "S": "test123"
        }
    },
    "NewImage": {
        "id": {
            "S": "test123"
        }
    },
    "SequenceNumber": "733400000000008471956488",
    "SizeBytes": 18,
    "StreamViewType": "NEW_AND_OLD_IMAGES"
}

Enter fullscreen mode Exit fullscreen mode

Summary

Congratulations. If you've made it this far then you successfully ...

  1. Scaffolded a new CDK app
  2. Created a DynamoDB table
  3. Created a Lambda Function
  4. Created a DynamoEventSource for the Lambda Function
💖 💪 🙅 🚩
thealexkates
Alex Kates

Posted on May 14, 2021

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related