How To Add New Cognito Users to DynamoDB Using Lambda

Nick Saponaro
HackerNoon.com
Published in
4 min readJun 12, 2019

--

That’s a lot of servers

Motivation

AWS provides some extremely powerful and useful tools for developers but figuring out how they all connect can be an arduous process. Many a developer have spent countless hours sifting haphazardly through documentation, forum comments, unanswered StackOverflow questions, and tutorials, only to find themselves back at square one with no code written.

One such instance where this affected me was in the event where I was attempting to authenticate new users with Amazon Cognito and subsequently add them to a DynamoDB database. This article is mainly written for my own reference but I hope that it will assist other developers who run aground and need a push back into the water without wading through a sea of code.

Ok, enough puns. Let’s get coding.

Pre-requisites

This tutorial assumes that you already have an Amazon Cognito UserPool set up as well as a Dynamo database with a User table.

Initial set up

Create an IAM Role for your Lambda Function

First, you will need to set up an IAM role for the Lambda function you are about to create.

Access your IAM Management console and select Roles from the left menu. Click Create role and select the AWS Service Lambda role. Once both are highlighted, click Next: Permissions.

For the purposes of this simple tutorial we are going to select:
1. DynamoDBFullAccess
2. AmazonCognitoDeveloperAuthenticatedIdentities
3. AmazonCognitoPowerUser

Click Next: Tags

Optionally set key-value pairs for your tags and click Next: Review

Name your role whatever you want, as long as it’s recognizable to you, and click Create role.

Create a new Lambda Function

Access your AWS Lambda dashboard and click on Create function.

Select Author from scratch, name your function and leave the Node.js 10.x runtime option selected.

Under the Permissions dropdown, select Use an existing role from the first dropdown, and select the IAM role you just created under the Existing role dropdown that appears below.

Click Create function.

Write your function

In the Function code window below the Designer, we can begin to create the function that will perform the actions necessary to add new users to the database.

Thank you to vbudilov for his starter code that helped me get started.

Paste the following into the Function code window.

Cognito to DynamoDB

What exactly is going on in this Gist?

The handler uses the aws-sdk DynamoDB API, which you can see instantiated at the top of the file but we need to establish some parameters (we’ll do that in a moment) before we actually call the method that will add the data to the database.

Once the variables are configured, a conditional statement exists that will only return true if an event is detected and the request includes userAttributes.sub, which is the unique identifier Cognito assigns to each new user.

We then create an object based on the AWS SDK DynamoDB API documentation that is passed to the putItem function and returns a promise.

Assuming the promise returns a successful response, the user is added to the database and the function is concluded.

We will talk more about how Lambda will detect an actual user sign up later in the article.

Set up environment variables

Take note of the following three variables:

const tableName = process.env.TABLE_NAME;    
const region = process.env.REGION;
const defaultAvi = 'https://YOUR/DEFAULT/IMAGE';

As well as this function:

aws.config.update({region: region});

While you could input your own TABLE_NAME and REGION, it’s best to use Lambda’s built-in Environment variables functionality to define those variables dynamically. You will find the Environment variables input fields just below the Function code window you are writing your function in.

As you would expect, you can fill the Keys in with REGION and TABLE_NAME and the Values in with your DynamoDB Table Name AWS Region respectively.

Modify the database parameters to your liking

You’ll notice that I created a database object with Item parameters that fit my database table. You should modify this section to fit your needs.

// -- Write data to DDB        
let ddbParams = {
Item: {
'id': {S: event.request.userAttributes.sub},
'__typename': {S: 'User'},
'picture': {S: defaultAvi},
'username': {S: event.userName},
'name': {S: event.request.userAttributes.name},
'skillLevel': {N: '0'},
'email': {S: event.request.userAttributes.email},
'createdAt': {S: date.toISOString()},
},
TableName: tableName
};

Test the function

Before we actually implement this new function with our Cognito User Pool, it’s important that we know it works the way we want it to, right? Luckily Lambda provides a fantastic test framework that allows you to submit requests with a simple JSON object.

Near the top of the Lambda Management Console, you will find a dropdown that, by default, says Select a test event. Click the dropdown and select Configure test events.

Enter a memorable name in the Event name field and paste the following code into the editor below.

Test user request

Again, edit the request to fit the database schema you have created.

When you’re satisfied with your test request, click Create.

Close the modal and click the Test button located right next to the event dropdown at the top of the page.

The test will return a response both in the header of the page and in the console of the Function code editor where you wrote the function.

Success!

Now, if you check your DynamoDB, you should actually see your new test user in the User table.

Create a post-confirmation trigger in Cognito

Access your Amazon Cognito User Pool and click the Triggers menu item on the left-hand side.

Find the Post confirmation card and select the Lambda function you just created and tested. Finally, click Save changes to save your work.

Now, when a user signs up via your Amazon Cognito sign-up form, they will automatically be added to your DynamoDB and can be managed in whichever way you see fit.

That’s it

Congratulations, you’ve created a Lambda function invoked by a Cognito post-confirmation trigger.

If you feel I’ve missed something or could improve this tutorial, please don’t hesitate to let me know in the comments!

--

--