We help forward-thinking leaders design, build, and launch exceptional digital solutions through a blend of AI, design, and technology.

Azure Cloud Services: A NodeJS Web & Worker Role Example

Microsoft Azure Cloud Services brand logo

In my last article, we looked from a high level at what it takes to build a scalable cloud-based app powered by Microsoft Azure. I talked about three major options for web apps: Azure Web Apps (also known as Azure websites), Azure Cloud Services, and Azure VMs. Today, we’ll dive in and create a simple app to see what’s involved in putting together and deploying an Azure Cloud Service.

Though Microsoft has written a helpful article for doing this, some critical details were left out. This guide is similar, but with extra instructions that hopefully will provide that “plug-and-play” experience you’re looking for, especially if you’re building a multi-role Cloud Service and bringing your own code. We’ll also look briefly at how you can run third party executables on your Cloud Service, which is the main reason for choosing a Cloud Service over a Web App. For additional information on managing and configuring cloud services, I recommend looking at Microsoft’s documentation (see sources at end).

There are two main types of roles that can be created within Azure Cloud Services: Web Roles and Worker Roles. For a detailed description of the difference between these two kinds of roles, see this Stack Overflow page, but in short an Azure Web Role uses IIS and is more or less ready to go as a public http endpoint out of the box. An Azure Worker Role is not, thus having a little more flexibility. Because of this, it makes sense to use a Web Role to implement your web service, which will be what end users connect to. The worker role can be used to run background processes and will probably not need to be accessed by users.

Separating these two roles is crucial for scalability. Each role is a separate virtual machine. Because they are separate, you can literally drag a slider bar in the Azure console to scale each role independently (more on this later in the article). Let’s dive in and create a Web Role and a Worker Role in the same cloud service, both powered by NodeJs.

Create a Cloud Service

The first step is to install Azure Powershell to make the job easier. This page explains both how to install Azure Powershell as well as connect it with your Azure account.

Once Azure Powershell is installed and configured, we can create the cloud service. Run Powershell as administrator and type the following command (note, you’ll want to change the name of the cloud service to your own unique name):

New-AzureServiceProject NodeJsExampleCloudService

This creates the cloud service project in the current working directory and opens it automatically.

Create a Web and Worker Role

Now let’s create the two roles.

To add the web role:

Add-AzureNodeWebRole WebRole
Set-AzureServiceProjectRole WebRole Node 0.10.21

To add the worker role:

Add-AzureNodeWebRole WorkerRole
Set-AzureServiceProjectRole WorkerRole Node 0.10.21

The result is the following folder structure:

Create a Web and Worker Role on Azure Powershell user interface

If you were wondering what the second command was for when I created the two roles, it is to set a specific version of NodeJS that the role will use. This is because the default is an old version of node and it is often necessary to use a newer version in order for third party modules to work properly. The version you select may depend on your application’s needs. To see the full list of available options, type: “Get-AzureServiceProjectRoleRuntime”.

There’s a couple things that should change at this point. Because we don’t intend to use the worker role as an HTTP endpoint, but will just be using it to run background processes, we may as well delete any endpoint that is added to the worker role by default. In the project folder, open ServiceDefinition.csdef. Under the entry, there should be an opening and closing tag. Delete that tag and everything inside of it.

Secondly, let’s make sure that when we test the site we know which role we’re looking at (for learning purposes). Inside the WebRole folder, open server.js, which was automatically generated by Powershell. Here we have the most basic NodeJs server possible:

var http = require(‘http’);

var port = process.env.port || 1337;

http.createServer(function (req, res) {

res.writeHead(200, { ‘Content-Type’: ‘text/plain’ });

res.end(‘Hello World\n’);

}).listen(port);

Change the “Hello World” line to:

res.end(‘Hello World from Web Role\n’);

If you open the WorkerRole’s auto-generated server.js file, you’ll notice it’s exactly the same. That’s ok for the purposes of this tutorial. Since we deleted the endpoint, that code should do nothing. Eventually you would want to replace this code with logic that does period server updates and background processing. The easiest way to do this is by having the web role and worker role communicate through the database (for example, the web role might add entries to Azure queue storage, and the worker role can periodically query that queue and perform the tasks that are entered there).

Prepare to Publish

You’re almost ready to publish to the cloud, but first you have to set up the publish settings. Powershell makes this easy. Enter the first command below, which will download a file that you must enter the path for in the second command. After finishing these commands successfully, delete the downloaded file for security:

Get-AzurePublishSettingsFile
Import-AzurePublishSettingsFile [enter path to downloaded file]

It’s also very helpful to enable remote desktop on your roles so you can connect to them and debug any issues that may arise when publishing (this command will prompt you to enter a username and password used for connecting to the VMs):

Enable-AzureServiceProjectRemoteDesktop

If your app deploys but a role shows up in the Azure Console as “busy” and never starts, you can connect to that role remotely to debug the problem (see “Remote Desktop Login” below for details on how to connect). Azure usually creates a folder on the remote instance called “approot” on one of the drive partitions. Open this folder and you should see the files for that role (for example, server.js). You can open a command prompt at this folder and type “npm start” to try to launch the node process and see what error it is returning.

Publish

Now that everything is ready, publish your cloud service, making sure to use the same service name you used before:

Publish-AzureServiceProject -ServiceName NodeJsExampleCloudService  -Location “West US” -Launch

This may take as long as 15 minutes to deploy. On subsequent publishes from this point on, you should only need to type “Publish-AzureServiceProject”. If the publish was successful Powershell will output a bunch of text about the published app, including a “url” entry which contains the web address where you can go to view the app.

Using Third Party Software on Your Cloud Service

One of the primary reasons to use a Azure Cloud Service instead of an Azure Web App (which is much simpler to set up) is because you need to run third party software that you can’t install on an Azure Web App. But how do you do that if a cloud service is not a persistent VM and can be recycled at any point? Logging in remotely and installing the software won’t help in this case. Sadly, though this is crucial to getting the most out of your cloud service, the documentation on how to do this in NodeJs is quite scarce.

It turns out that using third party software is actually quite simple. One of the most common scenarios is perhaps the need to run a third party command line executable. To do this, add the executable to a sub-directory inside the role that needs to use it (for example, the worker role). You can easily launch the executable asyncronously as a child processes:

var exec = require(‘child_process’).execFile;

exec(PATH_TO_EXE, [args], {}, function(err) {

If (err) {

…

} else {

…

}

})

It is important to note that this will also work on an Azure Web App in many cases, so it may not be necessary to utilize an Azure Cloud Service if you are doing little more than including a relatively small exe with your app. However, should you need to actually install third party software that it is unreasonable to include in the project directory as shown above, you will need to use a Cloud Service that runs a Start-up Task (see “Technique 2: Startup Task” on that page). The task will run whenever the VM is re-imaged so you’ll never have to log in remotely and re-install the software.

How to Scale

Now that your app is published, it is already possible to scale it. These settings can only be set in the Classic Aazure Portal (author’s note: The Classic Portal has been deprecated and is no longer available. This should now be possible from the main portal). On the main dashboard, select “Cloud Services” from the left menu and click on your new cloud service (“NodeJsExampleCloudService” in this example). This opens the following page:

Classic Azure Portal user interface

Choose “Scale” and you’ll see just how easy it is to set up scaling. Each of the two roles we created have settings that can be set independently. You can just drag the slider bar to increase the number of instances, or you can even set the app to auto-scale when a certain percentage of cpu usage is reached. These are the default settings for the WebRole:

Setting up role on Azure Powershell user interface

Remote Desktop Login

Since we enabled RDP access earlier, it’s quite easy to connect to the roles. In the Azure Classic Portal, click the “Instances” tab and then click “Connect”, which will open a Windows Remote Desktop session:

Setting up role on Classic Azure Portal user interface - Part 2

Summary

As noted in my last article, the architecture of your app must be set up so that it can take advantage of the scalability features demonstrated above. Assuming those things are taken care of, Azure’s got your back when your cloud service starts to gain traction. It’s really easy to get up and running with NodeJS-powered cloud services in Azure, and they remain a viable option for apps that are anticipating rapid growth.

Sources

https://azure.microsoft.com/en-us/documentation/articles/cloud-services-nodejs-develop-deploy-app/

https://azure.microsoft.com/en-us/documentation/articles/powershell-install-configure/

http://stackoverflow.com/questions/17654502/web-role-vs-worker-role-in-cloud-services-node-js

Sam Kilada