_Using AWS Rekognition and serverless, we can build a scalable member management system to replace membership cards._\n---------------------------------------------------------------------------------------------------------------------\n\nThis sample app is designed for clubs, gyms, museums (or even Costco )— any organization that has membership cards with a photo to gain access. With just a few serverless tools, we can develop a scalable, durable membership management system that uses facial recognition to keep track of members.\n\nThe app allows an administrator to enroll faces in their organization, and then verify new faces against the known membership list. In traditional app development, this would be a major undertaking but in serverless it’s easier than you might think.\n\nThe key takeaways in this project are that serverless lets us clearly delineate the front-end and back-end of a web-app, and by hooking code onto events fired by AWS services, we can benefit from massive scale and reliability with very little actual development. Our design looks like this:\n\n!(https://hackernoon.com/hn-images/1*2_fPxcOdbPEe0njYpgjgSg.png)\n\nIn this exercise:\n\n* We use VueJS on the front-end to create a mobile-friendly web app that will take photos and handle user interaction.\n* On the back-end we use API Gateway and Lambda to handle the interactivity with the front-end.\n* S3 stores all the images and a DynamoDB table keeps track of the facial data in those images.\n* Finally, AWS Rekognition does all the heavy lifting in enrolling and verifying faces.\n\n#### A quick walk-through of the final web app\n\nYou can test the end result by visiting [https://facematcher.jbes.dev/](https://facematcher.jbes.dev/). This is a live application intended for mobile phones and tablets (you can use Chrome tools to force a mobile layout, as shown below).\n\n**Please read this first** — every enrollment in the live hosted app joins a collection of members and the subsequent verification occurs against that _entire_ population of faces. If you choose to join, you are a permanent member so please don’t enroll your face if you are uncomfortable with having your facial data stored in the demo system.\n\n!(https://hackernoon.com/hn-images/1*h7dsA99J7fxgzsMQJ1VU6A.png)\n\nClick ‘Enroll’ to register your face — make sure you’re in a well-lit environment with your face looking forward towards the camera:\n\n!(https://hackernoon.com/hn-images/1*xRXTIQHSj88009tYbwJXpA.png)\n\nHey, I know that guy!\n\nAfter enrolling, click ‘Verify’ and take a photo of yourself — if it successfully matches, you’ll get a confirmation showing the original enrollment photo:\n\n!(https://hackernoon.com/hn-images/1*pLsFQELuXc04oRVPZ9OMgQ.png)\n\nJust a couple of quick caveats about this process. First, this sample app uses [getUserMedia](https://caniuse.com/#feat=stream) to capture the photo — some browsers don’t support this (including iOS) so you will need to use Firefox or Chrome for testing.\n\nSecond, the live hosted app above protectively shuts down if it’s used excessively (to save my wallet from unexpected charges), so if the system is unavailable, it’s due to over-use. This is only a demo environment but if you like what it does, you can launch the code in your own AWS account, which is what we’ll be doing in this tutorial.\n\nEverything in this exercise can be completed within the [AWS Free Tier](https://aws.amazon.com/free/), which includes ample facial recognition usage for testing. Having said that, it’s always possible to be charged for usage and you are always responsible for your own bill.\n\nFinally, you can also follow my walk-through at [https://www.youtube.com/watch?v=nyNKOYqZ3b4](https://www.youtube.com/watch?v=nyNKOYqZ3b4).\n\nOk, back to the code!\n\n#### Setting up Rekognition\n\nAWS Rekognition is not supported in every region so for clarity everything in this demo happens in **us-east-1** (N. Virginia). You will need to install and configure your [AWS CLI](https://docs.aws.amazon.com/polly/latest/dg/setup-aws-cli.html) first and then open a command prompt on your operating system.\n\nWe will be using a single collection within Rekognition called **askJames-faceMatcher** — to set up the collection, from your command prompt enter:\n\n aws rekognition create-collection --collection-id "askJames-faceMatcher"\n\nYou should see the output below, meaning your Rekognition collection is now ready to use.\n\n!(https://hackernoon.com/hn-images/1*7U2g26pLjEgTTHhnfEwCag.png)\n\n#### Setting up S3 and DynamoDB\n\nWe will need an S3 bucket for our app with public read permissions (for production I would recommend enforcing public access only through a CloudFront distribution but this helps keep the demo simple).\n\nWe are going to call the bucket **askjames-facematcher**\\-<_enter a random code_\\> — this will give you a unique bucket name.\n\nFrom the same command prompt, type:\n\naws s3api create-bucket --bucket askjames-facematcher-**RANDOMCODE** \\--region us-east-1 --acl public-read\n\nIf successful, you will see a JSON response similar to this:\n\n!(https://hackernoon.com/hn-images/1*yiN8LTqU8mG6HxdxJjScsg.png)\n\nNext, let’s create the DynamoDB table with on-demand capacity by entering the following:\n\naws dynamodb create-table --table-name askjames-facematcher --key-schema AttributeName=imageId,KeyType=HASH --attribute-definitions AttributeName=imageId,AttributeType=S --billing-mode PAY\\_PER\\_REQUEST\n\nYou should see the response below:\n\n!(https://hackernoon.com/hn-images/1*B0lu0LG5C9tglrnL348TTQ.png)\n\nThe back-end of this system is now set up — next, let’s configure the Lambda functions that will connect these services.\n\n#### Deploying the back-end glue.\n\nThe way this application works, when an image arrives in the S3 bucket, it triggers a Lambda function to fire, which then processes the image with Rekognition.\n\nYou need to download my code and deploy to AWS to make this work, so let’s set that up.\n\n* First, clone the code repository from [https://gitlab.com/jbesw/askjames-facematcher-backend](https://gitlab.com/jbesw/askjames-facematcher-backend) in to a directory on your machine — this contains all the Lambda functions we will be using.\n* Once downloaded, run `npm install` to set up the packages needed.\n* In case you haven’t installed Serverless framework before on your system (or you need to update), also run `npm install -g serverless`.\n* Finally, you must set your bucket name in **serverless.yaml** — enter your unique bucket name on line 14 (the UPLOAD\\_BUCKET variable).\n\nYou can now deploy this code with `sls deploy`, wait a minute for the magic to happen, then run `sls s3deploy` since we are using a plugin to hook up the S3 events to some code. You’ll need to take a note of the endpoints listed in the output since we will need this URL later:\n\n!(https://hackernoon.com/hn-images/1*WRCQxO9eqhw8mXYXsoqaNA.png)\n\n#### Testing the new back-end.\n\nWe are now ready to test the whole back-end of the application. Go to the S3 bucket you created earlier and create two folders called ‘enroll’ and ‘verify’. After you’ve finished, it will look like this:\n\n!(https://hackernoon.com/hn-images/1*yvDD5xrgAbFN0Qq8OFLFkg.png)\n\nYou’ll need two _different_ photos of the _same_ person’s face for the next steps, to test the photo enrollment and verification processes. Upload one of the photos to the **enroll** folder, and then check on your DynamoDB table to find a new record has appeared a few seconds later:\n\n!(https://hackernoon.com/hn-images/1*D5P3WdCDaQvSOGdCC2BfnQ.png)\n\nIn the result column, ‘INDEXED’ means the system has successfully found and enrolled the face in the Rekognition collection.\n\nGo back to S3 and upload the other photo of the person into the **verify** folder, and then refresh the DynamoDB table to see the result:\n\n!(https://hackernoon.com/hn-images/1*U0jhzPBHaBJudnFf63krGw.png)\n\nIn the result column, ‘MATCH’ indicates that Rekognition matched the photo with a face in the collection, and this DynamoDB item contains details of that match in the JSON attribute.\n\nWhat just happened? When you put a new object into the S3 bucket, depending on which folder you target will fire one of two Lambda functions. In the **enroll** folder, the process attempts to find and register a new face in the photo; in the **verify** folder, it will compare any face found against everyone already registered.\n\nThe key point is all of this happens serverlessly and independently of any front-end. Whether you copy 1 object into the bucket or 1,000 these functions will do their respective jobs and you are only constrained by your budget. The core of the app’s functionality has now been completed.\n\n#### Connecting the front-end.\n\nFaceMatcher has a VueJS front-end — this is a single-page application that communicates with the back-end via an API.\n\n* To get started, clone my front-end code from [https://gitlab.com/jbesw/askjames-facematcher-frontend](https://gitlab.com/jbesw/askjames-facematcher-frontend).\n* From the same directory run `npm install` to download all the packages it needs. Once installed, go to the **src** folder and open **main.js** — scroll down to lines 20–21:\n\n!(https://hackernoon.com/hn-images/1*M43XH_uOhIiHiETdZBHqeA.png)\n\n* For the API, enter the endpoint URL you saved from deploying the back-end. It will look similar to the one in the screenshot (only the code at the beginning should be different).\n* Next, enter the S3 bucket URL — for example, if it was **askjames-facematcher-123456**, the URL would be [http://s3.amazonaws.com/askjames-facematcher-123456/enroll](https://s3.amazonaws.com/askjames-facematcher2/enroll/1111.png).\n\nTo run the front-end application locally, enter `npm run dev` at the command prompt. Once the build process completes, visit [http://localhost:8080](http://localhost:8080) to see the app.\n\nIn Chrome tools (press F12), you can toggle the device toolbar to force the page to render as it would on a mobile device (it works best on mobile or tablet layouts).\n\n#### A quick recap.\n\nIn this serverless application, we built out a back-end by initializing the services we wanted to use first (Rekognition, S3 and DynamoDB). We then deployed the ‘glue’ functions that were fired when objects were uploaded to S3 — these events are the core part of the system. These functions stored the responses from Rekognition in DynamoDB.\n\nThe front-end actually does _very_ little — it takes a photo with your webcam or phone’s camera, requests an upload URL from S3 and pushes the photo up to the service. It then polls an API which checks with DynamoDB to see if the photo has finished processing, and displays the result.\n\nYou could deploy the front-end to S3 (as I did in the hosted app) by entering `npm run build` and copy the files in the **dist** directory to the bucket. The hosted app uses a CloudFront distribution and a custom domain name to finish out the deployment.\n\nCritically, although this app is simple, it’s extremely scalable and durable. The front end is loaded from S3 and there is no server acting as a single point of failure. The mechanism for facial analysis stores all the images in S3 and the results in DynamoDB. We do not need to back up the images or scale under heavy load.\n\n#### How does this compare with a non-serverless design?\n\nThe most common approach would use a web-server like Flask, Django or Express to generate the front-end code and manage the file uploading process and the interaction with Rekognition. This server would have to then store the images somewhere in a file system and maintain a database of files and their respective Rekognition responses.\n\nThe limitations with this approach are scaling, availability and effort — the server is a single point of failure and can only reach a certain capacity before scaling out is required. The amount of coding required to make this work would be considerably greater than the serverless approach illustrated here.\n\n#### What’s next?\n\nThere are many ways to improve the performance of the app, and the UI could be much more useful. In production, you would also want to add authentication to restrict usage.\n\nBut with this skeleton application, you can see that the core functionality is simple to build and deploy with serverless, thanks to the ease of using the managed services provided. We have built out a fully-featured member management system using facial recognition with very little actual code.