How to Deploy a Nodejs Express APP on AWS Elastic Beanstalk

How to Deploy a Nodejs Express APP on AWS Elastic Beanstalk

Building and deploying an application on the cloud can be time-consuming and a painful task, especially if like me you are new to cloud infrastructure.

Fortunately, there's a service in AWS that can simplify this task.

AWS Elastic Beanstalk provides an easy-to-use platform for deploying, managing, and scaling your applications in the AWS Cloud.

In this tutorial, we'll dive into the basics of Elastic Beanstalk, and then walk you through the process of deploying a NodeJS app connected to an RDS database.

There is no cost for using Elastic Beanstalk, but the AWS resources that it creates for this tutorial are live (and don't run in a sandbox). You incur the standard usage fees for these resources until you terminate them at the end of this tutorial. The total charges are typically less than a dollar.

Setting up: Create an AWS account

If you're not already an AWS customer, you need to create an AWS account. Signing up enables you to access Elastic Beanstalk and other AWS services that you need.

Sign up for an AWS account

If you do not have an AWS account, complete the following steps to create one.

To sign up for an AWS account
  1. Open https://portal.aws.amazon.com/billing/signup.

  2. Follow the online instructions.

    Part of the sign-up procedure involves receiving a phone call and entering a verification code on the phone keypad.

    When you sign up for an AWS account, an AWS account root user is created. The root user has access to all AWS services and resources in the account. As a security best practice, assign administrative access to an administrative user, and use only the root user to perform tasks that require root user access.

AWS sends you a confirmation email after the sign-up process is complete. At any time, you can view your current account activity and manage your account by going to https://aws.amazon.com/ and choosing My Account.

Create an administrative user

After you sign up for an AWS account, create an administrative user so that you don't use the root user for everyday tasks.

Secure your AWS account root user
  1. Sign in to the AWS Management Console as the account owner by choosing Root user and entering your AWS account email address. On the next page, enter your password.

    For help signing in by using the root user, see Signing in as the root user in the AWS Sign-In User Guide.

  2. Turn on multi-factor authentication (MFA) for your root user.

    For instructions, see Enable a virtual MFA device for your AWS account root user (console) in the IAM User Guide.

Create an administrative user
  • For your daily administrative tasks, grant administrative access to an administrative user in AWS IAM Identity Center (successor to AWS Single Sign-On).

    For instructions, see Getting Started in the AWS IAM Identity Center (successor to AWS Single Sign-On) User Guide.

Sign in as the administrative user
  • To sign in with your IAM Identity Center user, use the sign-in URL that was sent to your email address when you created the IAM Identity Center user.

    For help signing in using an IAM Identity Center user, see Signing in to the AWS access portal in the AWS Sign-In User Guide.

What is Elastic Beanstalk?

AWS Elastic Beanstalk is a fully managed service that helps you deploy, manage, and scale applications on AWS. It takes care of provisioning the required resources, such as EC2 instances, RDS databases, and load balancers.

Elastic Beanstalk also handles application deployment, monitoring, and maintenance tasks so that you can focus on writing code and delivering features.

PREPARE YOUR NODEJS SOURCE CODE FOR DEPLOYMENT

We cannot deploy our app straight to Elastic Beanstalk (similar to deploying at EC2). We need to follow a few steps before deployment.

To deploy your code you need a zip of our source code.

How to Deploy Your App.

Firstly make sure you have a start command in your package.json file. This start command should be configured to run your app. Beanstalk will execute npm start by default and it throws an error if it can't find it.

"name": "",

"version": "",

"description": "",

"main": "server.js",

"scripts": { "start": "node server.js" },

There's a super important thing about configuring environment variables. AWS follows pre-defined environment variables for RDS connections. Make sure you used the right naming. You can read this article by AWS for additional information.

we'll be using a query builder called Knex.js to connect our API to our database.

In the root of our project folder, create a file called knexfile.js where we'll specify the following database configurations:

module.exports = {
    development: {
        client: "sqlite3",
        useNullAsDefault: true,
        connection: {
            filename: "./data/dev.sqlite3",
        },
        pool: {
            afterCreate: (conn, done) => {
                conn.run("PRAGMA foreign_keys = ON", done);
            },
        },
        migrations: {
            directory: "./data/migrations",
        },
        seeds: {
            directory: "./data/seeds",
        },
    },

    production: {
        client: "pg",
        connection: {
            host: process.env.RDS_HOSTNAME,
            user: process.env.RDS_USERNAME,
            password: process.env.RDS_PASSWORD,
            database: process.env.RDS_DB_NAME,
        },
        migrations: {
            directory: "./data/migrations",
        },
        seeds: {
            directory: "./data/seeds",
        },
    },
};

create a folder called data, and inside it create a file dbConfig.js with the following:

const knex = require("knex");
const config = require("../knexfile.js");
const dbEnv = process.env.DB_ENV || "development";

module.exports = knex(config[dbEnv]);

Elastic Beanstalk (EBS) by default runs on port 8080. So we have to configure our app to run on port 8080. It's always a best practice to add the port number in environment variables and configure it in the EBS console.

const app = require("./src/app"); require("dotenv").config();

const port = process.env.PORT || 3000;

app.listen(port, () => { console.log("server is runing on port ", port); });

For Elastic Beanstalk to read our environment variables, we should add a file called .ebextensions in the project root directory with the following code:

commands:
    setvars:
        command: /opt/elasticbeanstalk/bin/get-config environment | jq -r 'to_entries | .[] | "export \(.key)=\"\(.value)\""' > /etc/profile.d/sh.local
packages:
    yum:
        jq: []

zip your code along with node_modules

Remember the zipped file should contain all files and subdirectories in the root folder and should not be inside any other folders. This is because Elastic Beanstalk will check for the package.json file in the root folder and it'll throw an error if it can't find it.

Now our app is ready, so let's create the Elastic Beanstalk application.

1) Sign in to your AWS Management Console, search and select Elastic Beanstalk from the Services menu. Click on the "Create Application" button.

Then select the Web server environment and provide a name for your app.

2) Choose Managed platform in "Platform type", and Node.js in "Platform", and leave the rest as it is.

Then choose Upload your code in the "Application code" section and upload the zip file. Set the version label and choose Single instance.

3) configure IAM roles. We need to create two IAM roles, one for Elastic Beanstalk and one for EC2

For the service role, select Create and use new service role. It'll automatically create and provide the required permissions

If you want to ssh into your EC2 instance via terminal, create a key-value pair and select it. Ignore this step if you don't want to login into EC2.

Create an IAM role with the following permissions and add the role to the "EC2 instance profile" and proceed Next.

  • AWSElasticBeanstalkWebTier

  • AWSElasticBeanstalkWorkerTier

  • AWSElasticBeanstalkMulticontainerDocker

4) Set up the database, turn on the Enable the database toggle and choose Postgres Engine. Fill out the other fields based on your needs.

5) Configure instance traffic and scaling

You don't need to change anything here unless you particularly need it. If you're building this sample app, leave the fields with default values. By default, Elastic Beanstalk will create an Amazon Linux machine.

6) Choose Basic in "Health reporting" and uncheck Managed updates activation. Add your environment variables and click Next.

7)Finally, review all your configurations and proceed with Next.

Once everything is done, you should be able to see that the health becomes green with "ok", and a domain URL will be generated.

if you are stuck leave a comment and I will be happy to help.