While the resulting example using serverless (see diagram below) makes it simple to get loopback running on AWS Lambda, there are a few considerations worth exploring further, which we will do in this article.
Note: If your loopback application is already running in multiple servers (e.g. load balanced), you may be already familiar with some of these challenges. In that case you may want to skip the loopback Overview section.
Why loopback on Lambda (serverless)?
Before even getting started on the techie talk, let us explore why you may want to run loopback applications on a serverless infrastructure (e.g. AWS Lambda).
The most common reason is cost reduction. For example, while your loopback application is only used sporadically, you incur the cost of running (virtual) servers around the clock. Serverless computing directly addresses that issue.
If infrastructure cost reduction is your goal, please make sure to account for associated costs like API Gateway and Lambda function warmer calls (more about these topics later on).
One loopback piece in particular, boot scripts, is of interest in this conversation. That is because boot scripts should be used by developers to run any code necessary to initialize their loopback REST API application.
Without getting in too much detail, boot scripts generally could be used to initialize:
- Application (code) state required by the loopback application to function properly.
- Data (database entries) required by the loopback application to be in place prior to its startup.
When a traditional loopback application is deployed to a (virtual) server(s), boot scripts are executed once prior to the application REST API being available to its clients. It is the responsibility of the (virtual) server(s) administrator(s) to ensure the proper resources are available to handle the application load.
AWS Lambda Overview
AWS Lambda on the other hand only uses up compute resources when they are required. So here are a few basic Lambda concepts you should be already aware of:
- “Any increase in memory size triggers an equivalent increase in CPU available to your function.”
- Lambda function are invoked when triggered by an external event.
- It is possible that at any given moment in time no Lambda instance (container) is running your loopback application, and one will only be spin up once a REST API call is received.
- Each Lambda instance will handle only one REST API call at a time. This means that if your loopback application receives simultaneous REST API calls, multiple Lambda instances will be spin up, one for each REST API call.
- Once instances are running, they stay “warm” and can be immediately reused by other REST API calls.
- Instances that stay idle for a while are discarded.
- Best Practice: “Keep alive and reuse connections (HTTP, database, etc.) that were established during a previous invocation.”
For more details check the AWS Lambda documentation.
AWS API Gateway Overview
It is important to point out that most likely you will use API Gateway to trigger your (loopback REST API) Lambda function.
This means that:
- Your loopback REST API will need to be somehow exposed to API Gateway (I will show you a quick way to do it later on, no worries ;-) ).
- Your Lambda function has to respond to API Gateway within 29 seconds, or API Gateway will consider it failed and respond back to the requester accordingly! (A partial solution: increase the lambda memory size so your code responds within the time limit).
loopback on AWS Lambda
At this point you surely realize that your existing boot scripts might need to be “tuned-up” as you port your loopback application to Lambda, so that:
- Datastore configurations are externalized. Regular parameter might be externalized by using environment variables and sensitive credentials by possibly using encryption or AWS SSM Parameter Store (see Additional Information section below for details).
- All database initialization is handled as part of your CI/CD pipeline, so every time new code versions are deployed the required database entries are updated accordingly.
- Boot scripts in Lambda function handling REST APIs only initialize code.
- Lambda function can handle REST API calls in a timely fashion by increasing Lambda function memory size so the corresponding boot scripts for that Lambda function complete within the desired time frame.
- Consider dealing with “cold starts” by using something like lambda-warmer or if you are using serverless, you may want to try serverless-plugin-warmup.
So, two factors are critical to size the Lambda function memory size for your loopback application:
- Time it takes to complete your boot scripts so your Lambda function can respond to REST API calls.
- Time is takes to complete the execution of your REST API invocation (should be less that the API Gateway limit of 29 seconds)
Make sure any datastore connection timeouts are long enough to be reused between invocations, for example by setting them to match possible Lambda idle timeouts.
serverless Framework — Simplifying Your Life
By now you start to see that while part of the challenge around porting your loopback to run on AWS Lambda is code development related, another important part is consistently managing the environment. If only there was some tool to help you accomplish that, huh? And that is exactly where serverless framework comes in!
Serverless not only provides a really simple way to make your loopback application be invoked as a Lambda function, it also offer a simple way to expose your REST API to API Gateway with 3 lines in serverless.yml!
And finally, serverless helps you consistently externalize datastore configuration through environment variables and centralized SSM Parameter Store management of secrets.
If you need to create a new database (let’s say an new MySQL server), you could even do that using serverless (although it requires quite a few lines).
- Re-deploying your service (i.e. serverless.yml file) will create a new lambda version and a new API Gateway deployment.
- Changing the name of you function from OLD_NAME to NEW_NAME in serverless.yml will delete the OLD_NAME Lambda function (and corresponding CloudWatch Logs) and create a NEW_NAME Lambda function (and corresponding CloudWatch Logs). So, backup your CloudWatch Log history (if you need to retain it) before renaming a function in serverless.yml!
- Some operations on RDS instances will cause the existing RDS instance to be removed and a new one to be created.
loopback and AWS SSM Parameter Store
Please note that at the time of this writing I was not able to retrieve parameter values from AWS SSM Parameter Store at runtime through boot scripts using loopback 3. The behavior observed was that loopback 3 would not wait for AWS SSM Parameter Store to respond before continuing on, even though loopback 3 documentation states otherwise.
REST API Mapping
Please note that there are other ways to map your existing loopback REST API to API Gateway. One of the reasons to use different approaches (a.k.a. patterns) would be to provide more granular monitoring and tuning of your functions, which might be particularly desirable in larger REST APIs deployments.
AWS Lambda Limits
Consider the following AWS Lambda limits when using AWS Lambda.
While it might be cost effective to port infrequently used loopback applications to serverless environments like AWS Lambda, I would recommend a more carefully assessing the impact of migrating higher load loopback applications to serverless environments to confirm the expected savings will be realized. A pilot project might be a good way to gain insight and make a more informed decision.
For a more in-depth understanding of serverless costs you may want to check out this article.