How to deploy Node.js application to AWS Lambda

In this article, we are going to learn how to deploy Node.js application to AWS lambda. AWS lambda is a function-as-a-service(FAAS) environment which provides pay only for the resources used based on the particular request measured in seconds or milliseconds.

To deploy Node.js application in AWS lambda, let’s create a simple node application. In this application, we are gonna view the list of posts created by the users and users can add the new post.

To accomplish this task we need:

  • An AWS account
  • Node.js and npm installed

Let’s create a simple node application and initialize an npm project and install common libraries:

mkdir serverless-test-app
cd serverless-test-app
npm init
npm install express body-parser ejs --save-dev

Once the libraries are installed, create the index.js file and copy the following code:

var express = require('express');var bodyParser = require('body-parser');var app = express();app.get('/',function(req,res){   res.send("Hello, World!").status(200);});app.listen(3000);

Run node index.js in your terminal and type “ http://localhost:3000/” on the browser to see “Hello, World!” displayed.

Let’s create a startup script in the configuration file- package.json :

"scripts": {  "start": "node index"}

Now run npm start in the terminal and navigate to http://localhost:3000 to see the “Hello, World!” displayed on the browser.

Navigate to http://localhost:3000

Now, create Posts.js file to keep the list of post in the memory. Add the below code to your Post.js file:

class Posts{
constructor(){
this.list = [];
}
add(body){
this.list.push(body);
}
getAll(){
return this.list;
}
}
const PostList = new Posts();
module.exports = PostList;

Now, create views folder and add index.ejs file in that folder. Here we are gonna display the list of posts. Paste the below code in the index.ejs file:

<html>
<head>
<title>List of Posts</title>
</head>
<body>
<div>
<a href="/add">Add New Post</a>
</div>
<% if(postList.length!=0){%>
<div>
<ul>
<% for(var item in postList){ %>
<li><%= postList[item] %></li>
<% } %>
</ul>
</div>
<%} else{%>
<p>No record found.</p>
<%} %>
</body>
</html>

Also, create add.ejs file where we are gonna add new posts. Paste the below code to add.ejs file:

<html>
<head>
<title>List of Posts</title>
</head>
<body>
<div>
<form action="add" method="post">
Add your post here: <input type="text" name="postName" />
<input type="submit" value="Add" />
</form>
</div>
</body>
</html>

Now paste the modified code to the index.js file:

var express = require('express');
var bodyParser = require('body-parser');
var PostList = require('./Posts');
var app = express();
//create request body
app.use(bodyParser.urlencoded({extended: true}));
app.set("view engine", 'ejs');
// get the list of posts
app.get('/', function (req, res) {
res.render("index", {postList: PostList.getAll()});
});
//add new post
app.get('/add',function(req,res){
res.render('add');
});
//submit the new post
app.post('/add',function(req,res){
PostList.add(req.body.postName);
res.redirect("/");
});
app.listen(3000);

Here, we set the view engine to ‘ejs’. Added a few routes to display the list of posts and a route to add a new post.

At this moment, the application should look like this:

Our app is ready, so we can now deploy it. Let’s install the Serverless framework and create a config file:

npm install serverless aws-serverless-express --save-dev

Now, create local.js, lambda.js and serverless.yml files in your application.

Prepare an entry point to lambda function, lambda.js :

const awsServerlessExpress = require('aws-serverless-express');
const app = require('./index');
const server = awsServerlessExpress.createServer(app)
module.exports.universal = (event, context) => awsServerlessExpress.proxy(server, event, context);

Replace app.listen(3000) code in the index.js file with module.exports = app.

But, to keep our app running locally, add the below code in the local.js file:

const app = require('./index');
const port = process.env.PORT || 3000;
// Server
app.listen(port, () => {
console.log(`Listening on: http://localhost:${port}`);
});

And edit the start script in package.json:

"scripts": {
"start": "node local"
},

Now install AWS CLI in your machine. I am using a windows machine, so this the link to AWS CLI for windows machine: https://docs.aws.amazon.com/cli/latest/userguide/install-windows.html

Once AWS CLI is installed, run aws configure in your command line. You will be asked to provide the following values:

  • AWS Access Key ID
  • AWS Secret Access Key
  • Default region name
  • Default output format

You have to create a new user in your AWS account using IAM service. Add provide the above details of the created user, along with the region where you want to deploy the service.

When the AWS CLI configuration is done, set up the serverless configuration. Place the following lines in the serverless.yml file:

service: serverless-test-appprovider:
name: aws
runtime: nodejs8.10
memorySize: 128
timeout: 10
stage: dev
region: us-east-1
functions:
api:
handler: lambda.universal
events:
- http: ANY {proxy+}
- http: ANY /

And deploy our function:

serverless deploy

If everything works fine, you will see the following output:

Service Information
service: serverless-test-app
stage: dev
region: us-east-1
stack: serverless-test-app-dev
resources: 11
api keys:
None
endpoints:
ANY - https://i96wsl5696.execute-api.us-east-1.amazonaws.com/dev/{proxy+}
ANY - https://i96wsl5696.execute-api.us-east-1.amazonaws.com/dev
functions:
api: serverless-test-app-dev-api
layers:
None

After invoking link from serverless command output (in my case: https://i96wsl5696.execute-api.us-east-1.amazonaws.com/dev), you should see your app deployed on AWS Lambda.

You may get an error 403 ({“message”:”Forbidden”}) when you try to add a new post. That is because the invoker URL is prefixed with a stage name. In my case, the stage name is /dev (URL: https://i96wsl5696.execute-api.us-east-1.amazonaws.com/dev).

So in both index.ejs and add.ejs file, add /dev prefix to your action URL:

<form action="dev/add" method="post">

Now we’re all set with our Node.js application on AWS Lambda!

Thanks!!Happy Coding!!.

I code for living.