Load balance Azure Web Apps Using Nginx Server

Azure Web Apps is a peculiar case as it uses ARR (Application Request Routing) by using cookies. By enabling this, they get the functionality of the sticky sessions. A session is called as sticky session when subsequent requests that are made within an established session get processed by the same instance of an app that served the very first request of the session. However if you’ve built your app to be stateless ARR actually limits scalability of your system. It also disallows the Azure Web Apps to be configured behind a highly efficient web server like nginx.

In this blog post, we’ll learn how to configure nginx server so that you can configure multiple Azure Web Apps behind it. 

Basic Infrastructure Setup / Pre-Requisites

We need to have minimum of two azure web apps and a linux virtual machine with public ip address to support this scenario. We’ll be using ubuntu server installed on a Azure virtual machine for this demo.

We have created below two web apps for our purpose:

First azure web app

Second azure web app

We have modified the text a little bit so that you see the difference.

Install and Access Nginx on Ubuntu Server

In order to proceed further, we first need to install nginx on the ubuntu server. The release version happens to be 17.10 in my case. However, irrespective of ubuntu server, it can simply be installed using below commands:

sudo apt update
sudo apt install nginx
Installing nginx on ubuntu server
Installing nginx on ubuntu server

If prompted for confirmation, press yes. Now, in order to access nginx website using Public IP address of azure virtual machine, we first need to add a allow rule for HTTP i.e. port 80 inside azure portal.

To do the same, we need to select the network interface for our virtual server in reference, and then add a rule for port 80 in the inbound security rules:

Allow incoming connections on port 80
Allow incoming connections on port 80 for Ubuntu Server

Once its done, we can now go ahead and access the nginx server to make sure that defult nginx setup is working:

Confirm that default nginx setup is working
Confirm that default nginx setup is working

Modify the Nginx Configuration

Now we need to modify the Nginx configuration so that we can achieve our requirement. For this we’ll be using vim editor. If its not installed on the ubuntu server, you can use below command to install it:

sudo apt install vim

Nginx stores its configuration in the nginx.conf file in the /etc/nginx directory. We’ll modify it to look like below:

user www-data;
worker_processes auto;
pid /run/nginx.pid;

events {
     worker_connections 768;
     # multi_accept on;
}

http {
     upstream backend {
          server Url01.azurewebsites.net;
          server Url02.azurewebsites.net;
     }

     server {
          listen 80 default_server;
          listen [::]:80 default_server;
          server_name localhost;

          location / {
              proxy_pass http://backend;
              proxy_set_header  X-Real-IP  $remote_addr;
              try_files $uri $uri/ =404;
          }
     }
}

where Url01 and Url02 are the azure web sites Urls that we want to load balance.

Now, we just need to restart the Nginx with the following command:

sudo systemctl restart nginx.service

Now, if we hit nginx server, we’ll get below page:

Azure web apps with default load balancer config inside nginx
Azure web apps with default load balancer config inside nginx

Due to ARR, we now need to pass the header to the Azure Web Apps correctly. This can be done by modifying our configuration to look like below:

user www-data;
worker_processes auto;
pid /run/nginx.pid;
 
events {
     worker_connections 768;
     # multi_accept on;
}
 
http {
     upstream backend {
         server localhost:8001;
         server localhost:8002;
     }
 
     upstream web01 {
         server Url01.azurewebsites.net;
     }
 
     upstream web02 {
         server Url02.azurewebsites.net;
     }
 
     server {
          listen 80;
          listen [::]:80 default_server;
          server_name   localhost;
 
          location / {
               proxy_pass http://backend;
               proxy_set_header    X-Real-IP    $remote_addr;
          }
     }
 
     server {
          listen 8001;
          listen [::]:80 default_server;
          server_name   web01;
 
          location / {
               proxy_set_header Host Url01.azurewebsites.net;
               proxy_pass http://web01;
          }
     }
 
     server {
          listen 8002;
          listen [::]:80 default_server;
          server_name   web02;
 
          location / {
               proxy_set_header Host Url02.azurewebsites.net;
               proxy_pass http://web02;
          }
     }
}

Where Url01 and Url02 are the azure web sites Urls that we want to load balance.
In above configuration, we apply a double proxy, so that we balance the input against the same ngin-x, attacking the ports 8001 and 8002, which headed to the webapps, but adding to the header the real WebAPP url.

We’ll need to restart nginx service again.

If we now hit the nginx server, we should be redirected to both of our web apps one by one:

Accessing azure web apps with nginx server IP address
Accessing azure web apps with nginx server IP address

Accessing azure web apps with nginx server IP address-2

6 thoughts on “Load balance Azure Web Apps Using Nginx Server

      1. Hi.. An app service does not have LB. You can have load balancer in app service environment. Also using Nginx server allows further customization like OCSP etc which Azure LB does not support.

        Like

      2. Hi.. There is no point of LB if it has only one endpoint in backend. I think I have made my point clear in the blog post. You may want to do some research on your end as well.

        Like

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s