Phone number verification with event-driven microservices using AWS Lambda, Kinesis Streams, React.js

AWS Lambda + CloudFront + Kinesis + DynamoDB architecture — phone number verification Web App & SMS

I recently built a prototype web app that performs phone number verification using an event-driven architecture pattern in Node.js on AWS Lambda with AWS Kinesis streams. This might be interesting if you are:

Source Code

phone-verification — phone number verification example project on Github

Full-stack Architecture

Front-end Web UI

Back-end Services

Step-by-step guide to implementation

0. Prerequisites

  • AWS Account
  • Install and configure the AWS CLI

1. Deploy the web app

  1. In the AWS Console, configure AWS S3 and AWS Route53 to establish static website hosting using a custom domain — see detailed instructions.
  2. Setup AWS CloudFront to serve the static website. See Host a Static Site on AWS, using S3 and CloudFront and then establish secure communication between the browser and web server Using HTTPS with CloudFront.

3. Clone, install, build, and deploy the web app.

$ git clone https://github.com/marksoper/phone-verification
$ cd phone-verification
$ cd webapp
$ yarn install
$ yarn build
$ cd build
$ aws s3 cp ./ s3://<your bucket/domain name>/ --recursive

2. Setup the database in DynamoDB

In the AWS console, create a DynamoDB table

Table name: VerificationChallenges
Primary partition key: createdDate (String)
Primary sort key: smsCode (Number)

3. Create a Kinesis Event Stream

In the AWS console, create a Kinesis stream

Table name: phone-verification-event-stream
Number of shards: 1

4. Create an “event log” Log Group in CloudWatch

This is essentially optional. If you don’t want this you’ll need to remove the code in each of the Lambda functions that logs to this CloudWatch Log Group.

Log group name: verificationEventLog

5. Create Three Lambda services with Serverless framework

The send-sms-verification-code Lambda function requires access to the Plivo API. Plivo API account authentication credentials are kept out of version control in a file called config.js. See the instructions in the project README for the expected format of this file.

You should also consider using AWS Lambda’s environment variables feature to make these credentials available. For this size app it probably doesn’t really matter, but for larger projects I would look carefully at both options.

Before creating the Lambda functions, you must edit the serverless.yml file, replacing < region > with your AWS region and < AWS Account ID > with your AWS account ID.

To create all 3 Lambda functions, from the repo root …

$ cd auth
$ serverless deploy -v

This will also create new roles and policies for these Lambda functions.

NOTE — at present Lambda does not support Node.js 7.x, so asyncawait is used to allow async await capability a la es7 in the Lambda functions.

Lambda function — auth-request-verification-code

Once created, test the auth-request-verification-code function in the AWS Console Lambda page by choosing Actions > Configure Test Event and entering input JSON:

{
"httpMethod": "POST",
"body": {
"phoneNumber": "< your testing phone number here >"
}
}

Lambda function — auth-send-sms-verification-code

The Serverless framework covers AWS Lambda definitions and associated roles/policies. But AFAIK it doesn’t deal with Kinesis mappings to those functions. Once both your auth-send-sms-verification-code Lambda function and your Kinesis stream are defined, you’ll need to update your Lambda to be invoked when stream records occur in Kinesis.

$ aws lambda create-event-source-mapping \
— region < enter your region here > \
— function-name auth-send-sms-verification-code \
— event-source < enter your kinesis stream ARN here > \
— starting-position TRIM_HORIZON

Once the mapping is created, it can be tested in the AWS Console using Actions > Configure Test Event OR by running the auth-request-verification-code function and using the CloudWatch logs to debug the flow through Kinesis.

Lambda function — auth-verify-verification-code

{
"httpMethod": "POST",
"body": {
"phoneNumber": "< your testing phone number >",
"verificationCode": "< your verification code >"
}
}

6. Testing

Front-end Web UI

Use standard create-react-app testing methodologies, including unit tests and the local web deployment feature (yarn start) for dev and testing of the web app.

$ cd webapp
$ yarn install
$ npm test
$ yarn start

Lambda Functions

Lambda functions can be tested manually using both the CLI and AWS Console. I used the AWS Console’s Lambda test invoke feature and CloudWatch Logs. A CloudWatch Log Group should be created automatically when you create the Lambda function.

Unit testing is challenging in AWS Lambda. I didn’t write any unit tests for this project. The are important implications on overall code organization — see this Unit testing guide from Serverless for example — that I would pay attention to in larger production projects.

Further Reading

Event-driven microservices

Event-driven architecture

Also published on my personal site at Phone number verification with event-driven microservices using AWS Lambda, Kinesis Streams, React.js