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.
- 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
- 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
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.
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.
If it is a static website, how can we show dynamic content?
Can this S3 website be put behind a domain name?
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.
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:
- User Sign-up
- Email / Phone verification
- User Login
- Social login with Facebook, Google etc.
- Forgot password
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.
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.
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.
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.