Getting started with Serverless Framework

Sharing is Caring

I have worked with serverless technologies like AWS Lambda since early 2016 when I left an established payment gateway and started working on a startup. For those not aware, there’s a lot of reasons to use serverless technologies: fast deployments, automatic scaling, pay per execution pricing, and more.

The Serverless Framework allows us to abstract away quite a bit of the complexity from setting up lambda functions and the necessary events to execute them, especially through the API gateway.

To get started with the Serverless Framework, we need to do the following things:

  1. Install it globally from the terminal
  2. Configure Serverless Framework Credentials
  3. Add it as a dependency to our project
  4. Set up the serverless.yml file

Setting up our local environment

The first thing we need to do is install the serverless framework globally. On windows you may need to start a command prompt with admin privileges. Once at the terminal we need to run “npm install -g serverless”

After that succeeds we need to configure out credentials. If you have not already, you will need to create an IAM user in AWS to get the secret key and access key.

To create an IAM user in the AWS Console, it’s best to find it by searching for “iam” or “users”.

Next, click “Users” and then “Add User”.

When creating a user it’s very important that we check the checkbox next to “Access Key – Programmatic access”.

Next, we take the credentials that we used from creating our IAM User and add them to serverless. To do this we need to execute the following at the terminal.

serverless config credentials –provider aws –key <aws access key> –secret <aws secret key>

For more details, here’s the AWS Config Credentials reference.

Adding Serverless As a Project Dependency

If you are starting a brand new project, it’s pretty easy to create a new project. Simply create a directory for the project and then change directory into it.

We can then run “serverless create” and if we pass a parameter of “–template aws-nodejs” we can automatically set up a lot of what’s needed.

Running this command creates three files:

  • .npmignore
  • handler.js
  • serverless.yml

.npmignore File

The .npmignore file is used to keep unwanted files out of an npm package. If there is no .npmignore file and there’s a .gitignore file then npm will ignore any files matched by the .gitignore file

The .npmignore file has the same structure – I usually just rename it to be .gitignore and start with it as my .gitignore file. If you aren’t sure what a gitignore file is, I have a blog article called Simple Git Ignore File For NodeJS that explains it.

handler.js File

The handler.js file contains our code for each function.

A best practice is to remove the majority of the code and put it into an external file that is then imported into the handler.

The serverless.yml file points to the handler.js file and what is being exported.

serverless.yml File

The serverless.yml file allows us to declare our functions in the service and how it will be deployed (plugins, events that trigger each function, resources, required, and etc.).

I then run npm init from the command prompt and just keep pressing enter to accept the defaults.

Setting up the serverless.yml file

When creating a serverless project, it’s a best practice to give it a meaningful name and keep in mind that one project can contain many functions. It’s usually best to think of it as a service amongst many services (ie: doing Microservices) instead of running a monolith.

I like to set my provider up like the following:

The main changes are setting defaults if no stage or region are passed in when doing deployments, setting environment variables in “{stageNameHere}.json” file that I don’t store in git.

I have also reduced the memory to be 256MB and will leave it at that until I’m certain there won’t be an impact. Although I haven’t done it yet I will usually set the logRetentionInDays to be 7 day once I’m ready to deploy to production. This is done in the provider section.

For debugging reasons and for the ease of developing locally, I will also usually use the plugin serverless-offline. You can read a lot more about serverless-offline in my blog post Running Serverless Framework Functions Locally

To keep my code relatively clean and help reduce costs a bit, I usually also include serverless-prune-versions.

To add these to my project I will need to do this using npm. I do the following from the command line.

And then finally, I have to include the plugins in the serverless.yml file.

The serverless framework works by creating a zip and uploading it to the cloud provider, if your project is set up like mine you will likely end up with a folder structure that looks something like this:

  • app (majority of my app logic)
    • controllers
    • middleware
    • models
    • routes
  • migrations (database changes)
  • node_modules
  • tests
  • seeds (inserting data into the database)
  • scripts
  • index.js (used for handler)
  • package.json
  • package-lock.json
  • serverless.yml

The more things in the zip, the slower the lambda potentially loads so it’s important to exclude thins not needed from being located in the project when it is being deployed.

So at the very bottom of my project, I include the following:

And finally, I’ve changed the function to work off of http. I’ve made the following changes.

By adding the “events” parameter I’ve hooked it into http and given it a path of “/hello” and said that it should use the GET method. I usually add support for CORS for everything because I prefer to use Angular or React for a frontend and they break for anything not returning cors headers.

Running my function locally

To start my functions locally for testing, I then can run sls offline –stage dev –region us-east-1 like this:

I can then call the api manually using something like Postman

Wrapping It Up

In this blog post, we looked at setting up a very simple API using AWS lambda.

Sharing is Caring

Brian is a software architect and technology leader living in Niagara Falls with 13+ years of development experience. He is passionate about automation, business process re-engineering, and building a better tomorrow.

Brian is a proud father of four: two boys, and two girls and has been happily married to Crystal for more than ten years. From time to time, Brian may post about his faith, his family, and definitely about technology.