Building apps that autoscale: Node.JS and AWS ElasticBeanstalk
Creating applications that scale automatically is easier than ever and does not require an entire Ops dedicated team if you know how to use the right tools. In fact, solo developers can build and maintain highly scalable applications on AWS.
In these series, we will be showing how to create and deploy applications that scale automatically based on demand and doesn’t require you to take any action (in most cases).
For this tutorial, we will be using Node.JS but you can apply the same concepts to multiple platforms, including Java, Go, Python, PHP, Ruby and .NET.
Creating a sample app
Assuming you have Node.JS installed, get to your terminal and install express-generator:
$ npm install -g express-generatorAnd create your app:
$ express elasticbeanstalkapp --view=ejsWhich will create the following directory structure:

Now install all dependencies and run the sample app:
$ cd elasticbeanstalkapp
$ npm install
$ npm startNavigate to http://localhost:3000 and you should see the “Welcome to Express” page.
One issue with running this express generated app on ElasticBeanstalk is that Express creates two files: app.js and bin/www. This won’t work right away due to how ElasticBeanstalk initiates your app:
Node Command–Lets you enter the command used to start the Node.js application. An empty string (the default) means Elastic Beanstalk will use
app.js, thenserver.js, and thennpm startin that order.
http://docs.aws.amazon.com/elasticbeanstalk/latest/dg/create_deploy_nodejs.container.html
To make it simple, let’s just rename the files:
$ mv app.js express.js
$ mv bin/www server.jsOpen server.js and change the very first require to:
var app = require('./express');And now you can run your server with:
$ node server.jsCreating a new ElasticBeanstalk App
Now that our sample app is almost ready, let’s setup ElasticBeanstalk. Login to your AWS Account and go to ElasticBeanstalk.
Click on “Create New Application”, top-right corner. Type in some info about your app and click “Next”.

ElasticBeanstalk will now offer to create the first environment for your new application:

Click on “Create Web Server” and then choose “Node.JS” and “Load balancing, auto scaling” as shown below:

Next page will ask about deployment packages and strategies. Leave everything as default for now and click Next. You could upload your custom app right now, but if ElasticBeanstalk fails when booting a custom app, it will fail badly and you possibly won’t be able to recover unless a new environment is created.

Next step is choosing your environment name and URL. You won’t be able to change these settings later so choose names and URLs carefully. There’s also a “Swap DNS” feature that we can leverage to change URLs later if needed, but that requires a new environment.

Now choose whether you want to build this environment inside a VPC or not. If you are not planning on using AWS ElastiCache for example, then you might not need a VPC, but it’s highly recommended.

Click here if you want to learn about databases on AWS Beanstalk. We will cover more on that topic in our next posts.
Leave Health Reporting as Enhanced (better reporting, higher costs) and set your Root volume to SSD with at least 20GB so you don’t get yourself in trouble (large rotation logs for example).

Next, on Configuration Details, choose an instance type, a keypair and your email address. If you don’t want to SSH into your boxes (and you shouldn’t unless it’s for dev purposes), leave it blank. Keep in mind that changing that key later is possible, but all instances will be replaced. Leave healthcheck blank for now. All other settings can be left as default, but you might need to disable or increase connection draining timeout depending on your app.

Set a name for your environment so it’s easier to identify resources later:

Under VPC Configuration, choose all regions for both ELB and EC2. You can use your default VPC Security group if you want to, but it’s recommended that you create a specific security group for this application (e.g.: myapp-beanstalk-prod). ELB visibility should be left as External.

Under permissions, you should create new instance profile and service role for this app. Unfortunately, if you try to create it now you won’t be able to select it unless starting a new environment. For now, leave as is.

ElasticBeanstalk should start now creating your environment:

And it should be ready soon.

Click on the top link and you should see this:

Deploying your app
It’s time to init git, commit everything (but node_modules) and build your package.
Create a new folder called builds and a new executable file build.sh that will zip everything necessary and create a file with a short hash so you know which version it is.
#!/bin/shhash=$(git rev-parse --short HEAD)
zip -r builds/build-${hash}.zip * --exclude=*builds/* --exclude=*node_modules/*
Make sure build.sh is executable and run it.
$ mkdir builds
$ chmod +x build.sh
$ ./build.shThis should create a file under builds/ called build-{short-hash}.zip
Now get back to ElasticBeanstalk and deploy it manually. Click on “Upload and Deploy” and select your zip file.

In a couple minutes, your app should be updated and running.
Auto Scaling
Now let’s setup AutoScaling. Go to the Configuraiton tab and then Scaling settings. You are most likely to be CPU-bound on Node, but if you are not please change your settings that best fit your app. In this example, let’s set Minimum instances to 1, Max to 4. We will auto-scale up when the average CPU usage is higher than 60% and scale down when CPU usage is lower than 20%. Only adding/removing 1 instance at a time, but you could use percentages instead for bigger clusters. Make sure that scaling down scale increment is always a negative number or you will add more instances instead of removing them when CPU usage is low.


Now let’s run Apache Bench and see how it behaves:
$ ab -n 5000 -c 50 http://host.us-west-2.elasticbeanstalk.com/
Congrats, you just built an app that autoscales based on demand!
Try these next:
- Create a /healthcheck endpoint and update your ELB settings
- Enable CloudWatch Logs and track data from all instances
- Setup SSL
