Building Serverless Websites in AWS - Intro
Nov 15, 2015
Serverless Websites
If you have a simple website (like a blog or portfolio), you don't need to necessarily pay for a server instance. You can host your HTML/CSS/JS files in some cloud service like Amazon S3 or Azure Blob Storage and configure your DNS to use them.
This blog is a serverless website. It doesn't require server-side processing neither a database. This approach has two main benefits:
- Infinite scalability: as you aren't managing a server instance, you don't need to worry about adding/removing new machines to your farm as your traffic grows/shrink. It will be smoothly handled by your Cloud Service and your content will always be served with the same low latency and high bandwidth.
- High availability: as your Cloud Service is responsible to handle the availability of your static content, you can expect up to 99,99% over a given year.
- Low costs: storage is much more cheap than CPU/RAM allocation. As an example, this blog costs only US$ 0.03 per month (the minimum of storage that is 1 GB). If I've used a server machine to host it, I would be paying at least US$ 10 per month.
So, that's great for a static content. But what can we do for dynamic websites? If my site needs authentication, page routing, server-side business rules and a database, what options do we have? It will need to spend CPU time and you can't escape from that, but if you use AWS Lambda, you can significantly reduce your costs and achieve infinite scalability.
As an interesting real case of building a serverless website, I recommend you to read this Reddit post.
Summary: an e-commerce website built with traditional tools/infra completely broke after being advertised by Valve in a blog post. After some rework using JAWS (later named as Serverless), AWS Lambda, S3 and DynamoDB, Valve advertised it again and they were able to handle 60k users requests in 2 hours with the cost of only US$ 0.07.
Quoting one of the comments:
It's a cheap cheap setup when you're not doing anything, and it only gets expensive when you're making a lot of money. That's a great thing for a business.
Serverless Framework (formely JAWS)
The Serverless Framework (formely JAWS) is an open-source framework that was created to help developers to build serverless apps using AWS features, mainly AWS Lambda (for code execution) and Amazon API Gateway (for Routing).
Instead of spinning up a full-blown server, the developer is invited to use a command line tool to deploy code-blocks to Amazon. Since each lambda function acts like a microservice and your app may end up with dozens of them distributed between multiple regions and managed by multi-developer teams in multi-stage environments, the Serverless Framework targets a better setup to avoid a messy solution.
I've created another blog post to show a simple example of how to use Serverless, but first you need to know what AWS technologies are involved.
The first thing that you need to be aware is that this solution is highly dependent on AWS. Usually, we would avoid being highly attached to a third-party solution. If AWS breaks forever, you will need some hours to adapt your code to be able to deploy it again at another host. However, AWS is so reliable and the benefits of serverless apps are so great that I would not be so worried about it.
AWS Lambda (Code Execution)
Lambda is a service where you can host your code and it will be executed when triggered by events. Lambda supports, currently, code written in JavaScript (Node.js), Python or Java.
Lambda is a managed service. It means that AWS is responsible for allocating machines on demand to execute your code and is responsible for high availability and to scale following your needs.
The code you run on AWS Lambda is called a "Lambda function". It needs to be stateless with no affinity to the underlying infrastructure. This prerequisite is what enables Amazon to rapidly launch many copies of the function to serve infinite scalability.
As everything in AWS, Lambda also have a "Pay Per Use" model. You will only pay for the computer resources that you use, but in this case, its much better than EC2 because your EC2 machines will always have some computer resources that are allocated for you but not necessarily in use and this allocation is charged. Regarding Lambda, you will allocate resources only for the duration of your Lambda function execution. That's why its a much cheaper solution.
In Lambda, you pay for the number of requests and the amount of memory-time you allocate for your requests. Currently, it costs US$ 0.0000002 per request (or US$ 0.20 per 1 million requests) and US$ 0.00001667 for every GB-second used (billing is metered in increments of 100 milliseconds). Also, the free tier includes 1M free requests and 400,000 GB-seconds of compute time per month and this bonus is given even if you have expired your 12 month AWS Free Tier term.
For example, if you allocated 512 MB of memory for a function that was executed 10 million times in one month and it ran for 500 milliseconds each time, you would pay only US$ 36.81.
How many server-side requests your user makes to access your site per visit? I would guess something like 100 requests. It means that US$ 36.81 served 100,000 users and each user has cost only US$ 0.0004 (not including data transfer costs).
Amazon API Gateway (Routing)
API Gateway is a service that lets you build RESTful APIs that acts like the "front door" of your application. It's the service that will receive all incoming requests, check authorization and route them to the underlying system that is responsible to handle it. In our case, it'll be AWS Lambda. API Gateway is also fully managed by AWS what means again high availability and scalability.
The following image shows an example of website that is fully serverless. The static content (HTML/CSS/JS) are hosted in S3, an user browses the page and click to see its local weather information, the API Gateway receives the request and triggers a Lambda function that will process it calling a DynamoDB database.
The pricing model is also "Pay Per Use". It currently costs US$ 3.50 per million API calls received plus US$ 0.09 per GB of data transferred.
Authentication
Amazon API Gateway has three options to handle authentication: Amazon Cognito, AWS Identity and Access Management (IAM) or OAuth 2.0.
Amazon Cognito is a service that allows you to safely store user credentials and these can be used in API Gateway as a token based authentication system.
IAM is the authentication system that is used for all AWS services. What API Gateway offers is a way to easily create API Keys, with fine-grained access permissions, to be distributed to third-party developers or simply to generate keys that will be used by your client devices (website or mobile app) to consume your API methods.
OAuth 2.0 is an authorization framework that enables your application to authenticate your users based on credentials controlled by third-party applications, like Facebook, Twitter or GitHub.
Serverless Databases
Amazon offers a service called RDS. It's fully managed and you don't need to worry about availability. However, it does not satisfy our objective to "Pay Per Use" and is not so easy to scale. As you have to allocate a database to run it, you'll pay per hour even if nobody is using your app.
The remaining options that we have are DynamoDB and SimpleDB.
DynamoDB solves the scalability difficulties that you would have using RDS and is a much more robust solution than SimpleDB. However, its pricing model also requires fixed costs to provision per-hour capacity. No usage means that you will still have some costs to handle.
SimpleDB have also a fixed cost of how much data you have stored, but the main cost is dependent on your usage. Your usage is measured in how many machine hours you spend to process your queries. Also, scalability is graciously handled by AWS and you can have bursts of increased usage without delays. If your app does not require complex queries and you have a very unpredictable usage, this solution may be best cost-effective.
To sum up
Below follows what we usually have in a dynamic website and what AWS feature we can use to build a serverless webapp.
- Static Content: the HTML / CSS / JavaScript code that runs at the client-side can be hosted in S3.
- Routing: API Gateway is responsible for receiving requests and to call the correspondent Lambda function.
- Authentication: IAM, Incognito or OAuth 2.0.
- Server-Side Code: Lambda functions handle each request.
- Database: DynamoDB and SimpleDB are a pretty scalable NoSQL database, where SimpleDB can be more cost-effective for unpredictable usage.
UPDATE: Dec 27, 2015
Replaced the JAWS reference to Serverless since it was rebranded.