We learnt in the first part how to host and securely distribute your static website with S3 and Cloudfront. The next natural step is then how to make that website not so dynamic anymore with a backend.
Usually building a backend from scratch can be painful to deploy and maintain, and in the past I would for sure have to delegate that task.
However, nowadays, you can do so with a few lines of code.
Thanks to AWS’s lambdas and the Serverless framework, you’ll be able to run a fully lightweight and functional backend with a few functions in no time.
I am going to walk you through this process with a real life example running on my website : 5e-pour-rien.com (it still means 5€ for nothing and yes it is still dumb)
Prerequisites
- An AWS account
- A live website
- Node installed
- The Serverless framework installed : npm install -g serverless
What are we going to build ?
The concept of my website is really simple: you pay 5€ for nothing and I send you a bill in which I include an electronic signature.
You can check that your signature is authentic on this page.
Although all of the processes described are done through Lambdas, I will only describe how I built the signature process for this article. (If you’re interested, let me know !)
The setup (if it’s not already done)
- Login into Amazon’s console and head on to IAM (Identity Access Manager).
- Click on Users and Add User
- Name it something like serverless-admin and tick Programmatic Access
- Then click on Attach existing policies directly and tick AdministratorAccess
- Click on Next to add Tags if you need them, and Create User to review and create your keys. Store your Access key ID and your Secret key in a safe place as we’re going to use them next.
- Next open your terminal and type:
- You’re all done !
Building the service
As a reminder, remember that when a user buys nothing, I send them a bill in which I include an lambda generated electronic signature.
The generation of the signature for a bill is very simple.
I encoded a string composed of the customer’s email and bill number. I used a base64 hash and a secret password to do so.
All in all, in essence the service we’re building is as follows :
- Get the signature from the website user
- Check if the signature is authentic
- Send the answer to the website
We’re going to build a Lambda as an API gateway to do so.
I built everything in Python3 but Lambda supports a ton of languages now (JS, Java, Node, Ruby…)
The meat
I used this encoding and decoding method explained in this StackOverflow thread. This is not by any means something ultra solid but it does the job for our use case.
You can try it for fun:
The lambda
A lambda is function which takes event and context as arguments. (You can see the test AWS proxy values for both right here)
You can trigger the code in the lambda based on the event passed. The event can be a lot of things :
In simple usage, it can be used to trigger code on a schedule with Cloudwatch Events, or as we’re going to do, an HTTP request.
The values of the event object change base on the nature of the event, but for an HTTP request, here’s what we’re going to focus on:
{
"body": "eyJ0ZXN0IjoiYm9keSJ9",
"resource": "/{proxy+}",
"path": "/path/to/resource",
"httpMethod": "POST",
"isBase64Encoded": true,
"queryStringParameters": {
"foo": "bar"
},
"multiValueQueryStringParameters": {
"foo": [
"bar"
]
},
"pathParameters": {
"proxy": "/path/to/resource"
},
"stageVariables": {
"baz": "qux"
}
}
These are the values of the test AWS proxy for an HTTP POST method with the value parameter “foo” having the value “bar” and the body having a value of “eyJ0ZXN0IjoiYm9keSJ9”.
Our case is fairly simple, we are simply going to parse the body of the event, which is going to be our assumed signature for our input.
As an output we want either the decoded string, or a message telling us the signature sent is not legit according to our decoding function.
So with that in mind, let us write our lambda function :
Pretty straightforward isn’t it ?
The output of a lambda used as an API gateway should always be a JSON like object with at least the keys statusCode and body. You’ll get errors 500 otherwise.
As is custom here, I return a 200 statusCode when the call is successful and 400 when it’s not.
All that is left now is to deploy our API. You could do it by hand using the AWS lambda interface, but Serverless handles that for you !
The serverless.yml file
It’s an option file that has to be at the root of your work directory that contains all of the information needed to deploy your lambda.
Deploying and testing our new API
At this point, my local folder contains three files:
lambda_demo
| serverless.yml
| decode_api.py
| encode_decode.py
We’re ready to deploy ! Just type:
serverless deploy
You should see Serverless working its magic and gifting you your brand new endpoint at the end !
You can also see that your lambda has been created in the lambda functions dashboard :
To test the endpoint, you can use any tool you’re familiar with, I personally like Postman. Simply copy your endpoint (in my case : https://s8zszn4fu2.execute-api.eu-west-3.amazonaws.com/dev/check), paste it into Postman, select the Body tab with the Raw option :
In that screen I pasted a legit encoded signature. Hit send and look at the bottom panel :
It worked to perfection ! Let’s see what’s happening if i don’t enter a properly encoded string like “skrttskrtttt” (shout out to Quavo):
Hmm, there’s nothing here:
BUT we get an important piece of information:
We get a 400 error, which is the desired answer since the string is not properly encoded.
If you remember, we were supposed to print out “This is not an authentic signature”.
It’s not lost ! It’s simply in your lambda functions logs.
Lambda Logs
Head on to the lambda dashboard and click on your function. Then click on the Monitoring tab and click on View logs in CloudWatch.
You find yourself on your Lambda’s logs, a report of every time your lambda has been triggered :
When I click on the log stream, I find these lines:
The lambda logs/Postman/Serverless combo is super efficient to debug anything super fast.
Congrats you have your backend !
You’re all done and it’s all it took, all you have to do next is edit your frontend to include your brand new api.
OH, by the way, Lambdas are probably super cheaper than what you considered or what you have at the moment since you get 1 million free requests per month.
Its just the perfect way to test stuff out !
Conclusion
Through these two articles learnt a few things, namely:
- How to host a website on S3
- Distribute it securely with Cloudfront
- Create a serverless backend with Lambdas
With this base the sky is the limit, and it gives a firm base to test out websites without emptying your pockets.
As for what’s next, there are things we haven’t talked about that I have implemented on my website :
- Securing your API routes with keys and usage plans
- Giving a custom domain to your API gateway endpoints
- Anything else I have not mentioned or detailed