I thought a good way to start my blog would be to go over the steps I took to create it. In choosing the technology stack, the first thing to know about me is I am a very cost conscious person, especially when it comes to recurring costs. I am also a huge fan of the latest technologies and finding if I can use them to create more efficient / performant solutions. As a result of that, for the past several years, I have been a huge advocate of Serverless technologies, AKA Functions as a Service (FaaS), with most of that experience focusing on Amazon Web Services (AWS) offering of Lambda.
For this blog I definitely knew that I wanted to go the serverless route; there is no way I would be OK with the blog requiring a VM or a container running for the site to be available. Strictly hosting static content was not an option because I wanted to have some interaction (like comments). In general, when creating solutions, I try to use AWS Lambda until the problem being solved proves in some way that Lambda is not the right answer, which is rare.
In addition to serverless no longer requiring a VM or a container running for the site to be available, it introduces some other great benefits as well. For example:
- Availability - with VMs and containers, if you want your solution to be able to sustain the loss of an availability zone (data center), you need to create a fully functioning application stack in multiple availability zones. With FaaS or Lambda, your function is not locked into an availability zone; it spins up where there is capacity when it is needed and is seamless for you.
- Scalability - with VMs and containers, if you want your application to support a peak of 10,000 concurrent users, you need to configure auto-scaling groups with scaling rules to start enough servers/containers to handle that many concurrent users (or just keep that many servers running 24/7... I've seen it done. ☹). With Lambda, your function is invoked in response to events and more events mean more invocations. There is nothing you need to do to prepare your lambda functions for this increase in demand.
- Infrastructure management - Sure with Lambda you may still need to manage its association with a VPC's subnets, if you need to connect to resources within your VPC, but you no longer need to manage servers, containers, AMIs, docker images.
I actually originally started creating this blog using the same approach that I have used for the last few years for most serverless projects, creating a Lambda function written in Python and then adding API Gateway to make the lambda available as an HTTP event. Then in my research, I was reading more about API Gateway being used as a direct proxy to other AWS services (which I had not leveraged before), with articles like these:
- AWS: Using Amazon API Gateway as a proxy for DynamoDB
- AlexDeBrie.com: Connect AWS API Gateway directly to SNS using a service integration
- ServerlessLand (Video): Building Happy Little APIs: Look Ma, No Compute! (S1E6)
As that first article had me thinking about this, I was realizing the most responsible way to create my blog would be simply using API Gateway as a service proxy to DynamoDB; no need to add another piece in creating a lambda that is simply retrieving the record from DynamoDB and putting it into the HTML format that we want the browser to receive. That solution would still have all of the benefits of serverless that I stated above, but would remove another piece, theoretically making it less complex. Let's ignore the complexity of Velocity Template Language (VTL) for now ☺. The high level architecture would look like:
Next, I would like to thank Andres Moreno for reviewing my initial draft that turned into this blog series and pointing me to his blog post, How to build a Serverless API in AWS without using a single lambda. Based on his feedback I cleaned up several things in this series, and moved to creating the APIs using the OpenAPI definition files rather than many CloudFormation resources as I was initially.
In this series we will be doing everything via CloudFormation, more specifically CloudFormation with the AWS Serverless Application Model (SAM) extensions. The serverless framework and terraform are great options as well, but AWS SAM is my current preference. Most importantly though, on all projects do everything as code, Infrastructure as Code (IaC). Doing things manually by hand is not recommended due to it being slow, error-prone, inconsistent, not scalable and not repeatable. So, it is important that everything in our project is defined as code, that way it is self-documenting of what is deployed, easily repeatable, ready to be moved into an automated pipeline and easy to iteratively improve.
If you want to run through this series of posts on your own, you will need:
- An AWS account
- AWS CLI installed on your workstation and configured with access keys to an IAM user that has sufficient permissions to that AWS account
- AWS SAM CLI installed on your workstation
- Then later for the Admin Page you will need NodeJS > 0.12.0
The rough plan I have in mind for this series is:
- Introduction (this)
- Planning the Data Model
- Creating the article page
- Adding the category and home landing pages
- Adding CloudFront
- Moving Static Assets to an S3 Bucket
- Adding Commenting Functionality
- Creating an Admin Page (with a WYSIWYG Editor)
If there is something else you would like to see, please leave a comment or message me on Twitter/LinkedIn (links on the right side bar).