Architecting Serverless Web Application on AWS

Problem Statement

A client wanted to design and architect a solution for creating a web application that is going to be used as a platform to conduct online exams. These exams can either be on-demand where a candidate can visit the website anytime and take the exam or the exam starts at a specific date & time where thousands of candidates will attempt the exam simultaneously. The solution must be deployed on AWS and should be able to handle large variation in traffic with minimum cost.

Business Objective

  • Solution should be able to handle tens of thousands of test takers at any time
  • Web application should be able to scale automatically with increase in user traffic
  • The solution should be low cost

Technical Objective

  • Architect a web application to run on AWS cloud with latest design paradigm
    It should be highly available within a specific region of AWS
  • No EC2 instances should be used to reduce effort on server management
  • No capacity planning to be required but services should scale automatically when needed
  • Users can sign up for their own accounts and can also login with their social media accounts
  • Database should provide consistent performance even as data grows over time
  • As development is going to be continuous process, put deployment automation in place

Design Factors

Why Serverless

Although cloud has made it easy to provision virtual machines, still there are a lot of responsibilities that we need to take care of e.g. capacity planning, configuring, patching, monitoring, scaling etc. Also, we need to design for fault tolerance and high availability.
Serverless designs take away all these responsibilities away from us and applications can be built on using a combination of managed services that scale per request. Most of them also charge us per request so it reduces the overall cost.

Web Framework

Since web application is not going to be deployed on server, we won’t be able to use web application frameworks that require server side processing e.g. php, java/jsp, asp.net etc.  

To create an application that renders directly at client’s browser, we will go with standard html, CSS, JavaScript with frameworks like bootstrap, angular.js or react.js.  

Frontend 

There is a need to host the application somewhere and since EC2 instances cannot be used, we can go with “Static Website” hosting from S3. This ensures the users can load the website directly on their browsers. It can store content like HTML, CSS, JavaScript, images and other required documents.  But this brings up two questions:  

If it is a static website, how can we show dynamic content? 

Can this S3 website be put behind a domain name? 

Second question is easier to answer as we can use Route 53 and create an alias record-set that maps to the S3 bucket endpoint. But to show dynamic content, client side application needs to use JavaScript/Ajax to make calls to some backend service in AWS and get the response with required data which needs to be shown on the website.  

Backend 

The frontend manages what information to show where on the website but then it must pick up that information from the backend. We can use a combination of AWS Lambda and API Gateway to create a layer that acts as our backed service. It would be exposed as REST webservice that can be consumed by frontend application to gather required information.  

Lambda functions run our code as stateless functions that can connect to the database and fetch the data. They can scale automatically as the number of requests increase so no capacity planning is required. And it is also a low-cost service that charges us for every 100ms of compute time used.  

API Gateway fronts the lambda functions and exposes our functions as RESTful web-service interface. This can either be unauthenticated web-service where anyone can come or an authenticated one where only valid users can use it. But first, we need to have a way to authenticate our application users.

Authentication

AWS provides user management and authentication with its service called Identity & Access management (IAM). But these are the users who need to have access to AWS management console or access to AWS APIs. But in our case, web application users do not need direct access to AWS APIs, instead they will be interacting with the custom API we exposed using API gateway. Let’s call such users as application users. And we need to have an authentication module that can do the following:

  1. User Sign-up
  2. Email / Phone verification
  3. User Login
  4. Social login with Facebook, Google etc.
  5. Forgot password

Instead of creating one of our own, we can use AWS Cognito which is a managed service and there is no need of have separate backend servers for authentication. Cognito also has an SDK for JavaScript that be used to create a signup/login section of the website.

Database

This could either be a Relational or NoSQL database, but using DynamoDB provides advantages of zero maintenance overhead and auto-scaling features. Moreover, hundreds of Lambda functions can easily interact with it over the API without running into problems like “max connections reached” that are very common with SQL databases.

Going Live

Since users will be loading static website hosted on S3, Cloud Front can help us improve the performance. Also, the Cloud Front distribution can be mapped with a Route53 domain.

Deployment Automation

As a final step, we need to automate the deployment for which we can leverage some of the automation services of AWS. The diagram below shows the deployment of fontend component to S3. Similarly, we can auto-deploy backend code to lambda. Also, it’ll be good to send out notification when deployment succeeds or fails. Since the client used slack as their communication tool, we integrated these notifications with slack using AWS Lambda.

Outcome

This design captures all the business & technical objectives and provides a scalable infrastructure that works without any severs to be managed. It was tested for 10,000 parallel test takers and it provided consistent performance. This architecture also saves a lot of operating costs as most of the services used are charged for their consumption and there is a very minimum recurring cost.

Quick Inquiry

Fill out my online form.