How to deploy a Node.js application to AWS Lambda using Serverless Framework
Tags: aws, node, tutorial, serverless
Published: 2021-10-22 10:29:19

Being a developer is awesome. Writing code, solving problems, and thinking of ingenious solutions for complicated algorithms is what we live for. But, the grass is not always so green on this side of the fence. Sooner or later, you need to get your hands dirty and deploy the app you worked so hard on. Deployments are not always easy. To be blunt, they can be challenging and time-consuming. That's what we'll solve in this tutorial.

![](https://miro.medium.com/max/1400/1*UWjEaoVpjzL8pbYnzs5GKw.png)

*For copyable code snippets, *[*see the original article*](https://dashbird.io/blog/how-to-deploy-nodejs-application-aws-lambda/)*.*

Goals
=====

Today you'll learn how to deploy a Node.js application to [AWS Lambda](https://aws.amazon.com/lambda/) with the help of [the Serverless Framework](https://serverless.com/).

The walkthrough will also cover a real-life scenario of deploying a production version of your application, with environment variables, [proper monitoring](https://dashbird.io/serverless-observability/), and, of course, [easy debugging](https://dashbird.io/aws-lambda-troubleshooting/). Oh, how I love seeing nice stack traces!

Prerequisites
=============

This tutorial will need you to have a few simple things set up already. Don't worry, it won't be long and will cover just the basics.

-   [AWS account](https://aws.amazon.com/console/) --- AWS has 12 months of free tiers and plenty of lifetime free tiers, so don't worry about breaking the bank.
-   [Node.js and npm installed](https://nodejs.org/en/download/) --- Here's a quick reference for making sure you have them installed.
-   [Serverless Framework installed](https://hackernoon.com/a-crash-course-on-serverless-with-node-js-632b37d58b44#422a) --- Check this out for an excellent reference and follow steps 1--3.
-   [Dashbird account](https://dashbird.io/features) --- This will give us the required overview to see what's happening to our app.

Ready? Let's go!

*For copyable code snippets, *[*see the original article*](https://dashbird.io/blog/how-to-deploy-nodejs-application-aws-lambda/)*.*

What's AWS Lambda?
==================

AWS Lambda is a pay-as-you-go serverless compute service, which means what now? Well, you just deploy your source code to AWS, and they handle the rest. Amazing! No need to fiddle with servers, ssh connections, Linux, or Vim. But, want to know what's even better? It scales automatically and has no downtime. I'll let that sink in...

The technical definition for AWS Lambda would be a Function as a Service. You deploy some code; it gets invoked, processes some input, and returns a value. Simple!

Hold up a sec. We need to mention a crucial fact. All lambda functions are stateless, meaning they cannot store persistent data. And, if I just said Function as a Service, how do we deploy a whole Node.js application to AWS Lambda?

How Does It Work?
=================

When you think about it, it's not that complicated. A single lambda function is essentially just a tiny Node.js runtime environment. You can run whatever you want in there. That's what we'll do, package up a Node.js app and send it off to AWS Lambda. Sneaky.

What Will We Deploy?
====================

The code we'll be deploying is just seven lines long to make this example as simple as possible. However, it could be as large as any Node.js application you have in production, and it would all work like a charm. Intriguing...

How Do We Deploy It?
====================

In comes the Serverless Framework like a horse riding a white knight! Hold up; I may have that backward.

Anyhow, this excellent framework enables us to both develop our apps locally, just like we're used to, but also deploy them with a straightforward command. Hmm... tell me more.

Let's Get Coding!
=================

First thing's first. Open up your terminal; we need to install some packages. Yay, installing stuff, love it!

1\. Install and Configure the Serverless Framework
==================================================

*$ npm install -g serverless*

Prefix the command with `sudo` if you're running this command on Linux.

![](https://miro.medium.com/max/1400/1*f07DB-LclnGa-PDprWnumg.png)

*For copyable code snippets, *[*see the original article*](https://dashbird.io/blog/how-to-deploy-nodejs-application-aws-lambda/)*.*

Make sure to add your IAM User's public and secret key instead of the placeholders I specified above. The user needs programmatic access and admin permissions. [Here's the official guide in the AWS docs](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_users_create.html#id_users_create_console).

2\. Create the Boilerplate Code
===============================

Let's create a new folder and give it a unique name. Jump over to your terminal and run the commands below.

*$ mkdir serverless-nodejs-app **&&** cd serverless-nodejs-app*

Excellent, now what's left is to run the create command to generate some starter code for us. This is called a serverless service.

*$ sls create -t aws-nodejs -n serverless-nodejs-app*

Only one more step before opening a code editor.

3\. Installing Dependencies
===========================

Like you can see in the code snippet above, we need to install a few modules first. Lucky for us, there are only two, and it's as simple as running one command.


![](https://miro.medium.com/max/1400/1*kCBDumtkDwf0FYTQarEUgA.png)

*For copyable code snippets, *[*see the original article*](https://dashbird.io/blog/how-to-deploy-nodejs-application-aws-lambda/)*.*

That's it! Let's open it up in a code editor and do some actual coding.

4\. Coding For Real
===================

Once you open up the code editor, you'll see three files. Ignoring the `.gitignore file`, let me explain what the `handler.js` is first, then I'll move on to the `serverless.yml`. The handler will hold all your app logic, all the code. In contrast, the `servereless.yml` is the configuration file for the resources you'll be creating on AWS.


![](https://miro.medium.com/max/634/0*hJ_ArZ42uAVwD1Dz)

Go ahead and rename the `handler.js` to `app.js`, just to simplify us to figure out what goes where.

Delete all the starter code and paste this code snippet into the `app.js` file.


![](https://miro.medium.com/max/1400/1*zOQyTjrobsn2uJpS7hKwdw.png)

*For copyable code snippets, *[*see the original article*](https://dashbird.io/blog/how-to-deploy-nodejs-application-aws-lambda/)*.*

Seven lines of code? It looks familiar, right? Just like you're used to. That's it. Believe it or not, there's nothing more to it. Let's move on to the `serverless.yml`.

Once again, delete all the boilerplate code and paste this in.


![](https://miro.medium.com/max/1400/1*xuvu5WQjWFdVu8fcw85ZzQ.png)

*For copyable code snippets, *[*see the original article*](https://dashbird.io/blog/how-to-deploy-nodejs-application-aws-lambda/)*.*

Done! All that's left is to deploy it.

Ready to Deploy!
================

Switch back to the terminal window. By running one command, your app will be deployed.

*$ sls deploy*

The Serverless Framework will now wrap everything up into a nice bundle, create a CloudFormation file from the *serverless.yml* and shoot it off to AWS S3. Once the resources are created, and the code is deployed, you'll see an endpoint sent to you in the terminal.

![](https://miro.medium.com/max/1400/0*YpslR8q6QeyoYngH)

Opening up the provided URL in a browser, you'll see *"Hello World!"* get sent back to you.

Deploying to Production!
========================

This is great and all, but not ready for a production environment... yet. Worry not! You'll be surprised how simple it is to make it production-ready.

1\. Add a `secrets.json` file for environment variables
=======================================================

For now, let's just add the `NODE_ENV` in the `secrets.json`.

![](https://miro.medium.com/max/1400/1*UcdUBWK5LkE3Wv-G9Gpnlg.png)

2\. Add a reference for the `secrets.json` in the `serverless.yml`
==================================================================

As simple as adding the secrets file, it's even easier to reference the file in the `serverless.yml`.

![](https://miro.medium.com/max/1400/1*JS-9PZEUDt4b42RXJQ4FzA.png)

*For copyable code snippets, *[*see the original article*](https://dashbird.io/blog/how-to-deploy-nodejs-application-aws-lambda/)*.*

Amazing, that's it! Delete the `node_modules` and `.serverless` folders from the service and run npm install again, but this time with the `--production` flag.

*$ npm install --- production*

Great! All that's left is to re-deploy the service, and you're set.

*$ sls deploy*

And this is what we end up with.

![](https://miro.medium.com/max/720/0*3aErKjyC-Wyoj-UJ)

I guess we're done? Not really.

Having an app running in production just because you installed npm modules with `--production` doesn't cut it. To be able to sleep well at night, I need a bit more. Here's where proper system insight and monitoring tools come to play.

Let me show you.

How to Gain Insight Into Your System?
=====================================

The #1 problem with all serverless applications is their distributed nature. Plain and simple, it's impossibly hard to have an overview of all the things going on. Not to mention how hard it is to debug when something goes wrong.

To calm my fears, I use [Dashbird](https://dashbird.io/). It's a simple monitoring tool that doesn't require me to change any code and has no overhead. So, no performance hits either. Nice!

Thankfully, they have sensible documentation, which makes the onboarding process a breeze. Go ahead and follow their [Quick Start guide](https://dashbird.io/docs/quickstart/setting-up-dashbird/). Don't forget to come back here, though.

Once you're done, all the requests will start piling in one by one, and you should see something like this.

![](https://miro.medium.com/max/1400/0*VW0FxSJ60thYmGoN)

The function details will give you an overview of how the function behaved over time, so multiple invocations are aggregated here.

If you click on a recent invocation at the bottom left, you will drill down to the invocation level of details that comes with tracing and logging data.

![](https://miro.medium.com/max/1400/0*W2XBuVbWR3WbNpNL)

Wrapping Up
===========

This was fun!

Lambda is awesome! When combined with HTTP event triggers such as [API Gateway](https://dashbird.io/knowledge-base/api-gateway/what-is-aws-api-gateway/), development tools like the Serverless Framework, and observability tools such as [Dashbird](https://dashbird.io/), things just become so easy.

This simple API example we coded above is just a proof of concept. But you can see the point. It gives you a starting point from where you can create awesome production apps!

If you missed any of the steps above, [here's the repository with all the code](https://github.com/adnanrahic/express-sls-app).

*Further reading:*

[How to check NFT supply with AWS Lambda](https://dashbird.io/blog/nft-aws-lambda-serverless-blockchain/)

[How to test serverless applications](https://dashbird.io/blog/how-to-test-serverless-applications/)

[Top 6 AWS Lambda monitoring tools](https://dashbird.io/blog/top-aws-lambda-performance-monitoring-tools/)

[How to solve serverless cold starts](https://dashbird.io/blog/can-we-solve-serverless-cold-starts/)

[AWS Lambda Node.js errors and exceptions](https://dashbird.io/event-library/aws-lambda/aws-lambda-node-js-errors-and-exceptions/)