This lab should help you to deploy your node app from the EWD module on AWS for scaling and load balancing.
These initial steps are identical to the start of the TLS lab we did a few weeks ago.
Go to AWS and select the EC2 service
Launch a micro instance using the default Amazon Linux 2 AMI
At Step 6 (Configure Security Group), create a new security group that allows access to TCP port 3000 as well as 22/SSH
Connect to your instance using SSH
On your instance, install the current version of nvm (node version manager):
curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.34.0/install.sh | bash
. ~/.nvm/nvm.sh
Next install node 10.15.3 LTS and npm and the latest version of hapi (on your instance):
nvm install 10.15.3
npm install hapi
You may wish to test everything is ok by downloading the very basic Hapi "Hello World" application provided here. Start the application with:
node hapi_example.js
and point your browser to http://ip-address:3000, replacing ip-address with your instance's IP address
Here we will deploy the final version of the donation-web sample app (from Eamonn de Leastar). This application uses a mongo database, which we configure first.
Firstly you will need to configure yum to find mongodb:
# SSH into your instance first
sudo nano /etc/yum.repos.d/mongodb-org-4.0.repo
Then enter the following into this file:
[mongodb-org-4.0]
name=MongoDB Repository
baseurl=https://repo.mongodb.org/yum/amazon/2013.03/mongodb-org/4.0/x86_64/
gpgcheck=1
enabled=1
gpgkey=https://www.mongodb.org/static/pgp/server-4.0.asc
Then install and run mongod:
sudo yum install -y mongodb-org
mkdir db
sudo mongod -dbpath db --bind_ip_all
From another terminal, make a new SSH connection to your instance and download and configure a recent version of the donation web app
curl https://codeload.github.com/wit-hdip-comp-sci-2018/donation-web/zip/donation.11.end -o donation.zip
unzip donation.zip
cd donation-web-donation.11.end/
npm install
Create a .env file
nano .env
and add the following to it
cookie_name=donation-web
cookie_password=secretpasswordnotrevealedtoanyone
db=mongodb://localhost/donation
Now start the server
node index.js
If your application runs on a single instance, you can deploy a local database on that instance. However this is not a good design from the perspective of fault tolerance, high availability and scalability. Configuring auto scaling and load balancing on such an application could result in data inconsistency as we would have multiple non-replicated copies of the database.
Launch a new EC2 instance and use a security group that has the default mongo port (27017) open. N.B. This should normally always be done in a private subnet as exposing databases to the public Internet is a major security risk. For this practice exercise though we will keep it public to make it easy to log in using SSH and carry out some configuration. Tag this instance 'database'
Install and run mongod on this new 'database' instance (as in previous step of lab)
Go back to your other instance where donation is installed and edit the .env file
nano .env
to point it to the database instance. Change 'localhost' to your database instance's private IP address.
cookie_name=donation-web
cookie_password=secretpasswordnotrevealedtoanyone
db=mongodb://172.1.2.3/donation (replace with correct IP address)
When creating the Launch Configuration for scaling you can specify a script to run at startup at Step 3 (Create Launch Configuration) - Expand Advanced Details and enter your script under User Data. The following would start the sample app.
#!/bin/bash
su - ec2-user -c 'cd donation-web; node index.js'
Note that this can also be done when launching instances manually.
If your app uses sessions for authentication of requests after users log in and sets a session cookie, then you'll need to enable stickinesss. This means that the load balancer binds a client's session to a particular target instance for a specified period of time. This makes sure that a sequence of requests from a particular user to the app all go to the same target.
You can only configure sticky sessions after completing the wizard to create the target group.
As an alternative, classic load balancers can be configured for session stickiness that is tied to a target instance's session cookie.
When creating an application load balancer, you configure ports in two places:
The first is the port the load balancer listens on. The second is the port your target application listens on. These do not need to be the same port number.
For a node app, you might wish to have the load balancer listen on the default port and forward the traffic on to port 3000 on the targets. Then you would browse to http://lbname rather than http://lbname:3000. Note that your security group configuration needs to be consistent with the choices you make here.
You also configure the path for HTTP health checks in Step 4. The default route is '/'. This should be changed if your app does not listen on this path.
To show the local hostname in a browser and log test requests to the console, you could use the value of os.hostname() by editing routes.js to have:
const os = require("os");
and add a route like this one (in routes.js)
{
method: 'GET',
path: '/testlb',
handler: function (request, h) {
return('Server: ' + os.hostname());
}
},