Getting started with a Practical Serverless Setup on AWS — using Lambda, API Gateway and RDS
Creating a serverless project on AWS using Lambda, API Gateway and RDS can be simple at first but as your project progresses, management of code, libraries, deployment and testing can become tedious.
For example, say you have multiple lambda functions each sharing libraries and helper code. How could we manage all this without maintaining seperate code bases for each function and uploading these functions to Lambda in a .zip file every time we went to update or test it?
Let’s base the tutorial off a simple project, an API that can list and create different types of ice cream having it’s data stored in a relational database (MySQL) which will be hosted on RDS. We will be using the Node 8 runtime environment complete with ES6 capabilities including the usage of Async Await.
The local environment assumed in this tutorial is macOS 10.12 with the AWS SDK, Node 8 and NPM installed. All code can be found on my GitHub.
Please make sure to follow this guide with the repository I have created on GitHub
Setup and Project Explanation
For this project we are using Apex (http://apex.run), a command line based serverless management tool. Apex is by far the best serverless management tool for AWS Lambda I have seen to date. Apex will assist you in building, deploying and testing Lambda functions with ease. It will allow you to remove the use of the Lambda GUI from your project completely allowing you entirely to focus on your code and less on it’s deployment.
Our directory setup will be roughly as follows (the functions folder and the project.json file is needed for Apex to work).
│ └── index.js
│ └── function.json
This is the main JSON file apex will reference for your Lambda’s configuration when working with your individual Lambda functions.
"description": "Practical Serverless AWS",
"build": "../../node_modules/.bin/webpack --config ../../config/webpack.config.js --bail",
"clean": "rm -f main.js"
Besides the self explanatory parameters, heres an explanation of the rest:
- “role” — The role for your functions can be found or created in your IAM console. It is also created automatically when adding a new function in the Lambda web based interface
- “profile” — Found in your AWS credentials file in “~/.aws/credentials” . Make sure to set the region of this profile in “~/.aws/config” as well
- “hooks” — The life cycles of the Lambda deployment. Here we are using build, to build the lambda code and clean, to remove the built file after it’s deployed
- “environment” — Lambda environment variables. This will contain all environment variables that will be accessible to all lambda functions within your project. Please keep in mind to not commit passwords to your repository
Your normal Node.Js package file
This is where your lambda code will live. Both index.js and test.js will live in here along with other helper classes. The index.js file will be the entry point to your function. The test.js will allow us to test the function locally.
This file will allow us to overwrite the common project.json specifications and have custom properties on a per function basis. For example, below we have specified a function specific description and timeout.
"description": "Get Ice Cream",
Although not necessary for Apex to work, we can place common files here such as a database helper class. We can then symbolically link to them in each function. For example in the directory of the function, you would link to the common file using the unix symlink command
$ ln -s ../../common.js common.js
Let’s create a schema for our RDS instance, (the schema used in the repository’s example Lambda functions)
CREATE TABLE `DatabaseName`.`IceCream` (
`idIceCream` INT NOT NULL AUTO_INCREMENT,
`Name` VARCHAR(45) NULL,
`Flavour` VARCHAR(45) NULL,
`Rating` INT NULL,
`Colour` VARCHAR(45) NULL,
`NextOrderDate` DATETIME NULL,
PRIMARY KEY (`idIceCream`));
Be sure to note your host, user name, password and database name of your RDS instance for the environment variables as specified in the project.json file.
Deployment and Testing
Next is the testing and deployment of our functions. For this you will need to have Apex installed and the project.json file edited accordingly. Please see the Apex site for the latest install instructions. Make sure your working directory is the root of the project.
$ cd path/to/project/
To List all the functions and their deployment status.
$ apex list
To deploy to Lambda
$ apex deploy
or if you want to deploy a single function
$ apex deploy myFunction
If you check the lambda console, these function will now appear in their transpiled form.
$ DEVELOPMENT=true node functions/GetIceCream/test.js
Invoking the function remotely
$ apex invoke GetIceCreaResults
Although this is not an API Gateway management guide, I have used the stock standard API Gateway web based interface to manage my API’s as this is always a one off process. Once I have created my API’s I export the API’s into a swagger file for backup purposes.
As you can see, once all setup this is a fairly easy process to now test and deploy your lambda functions in a project of any scale.