Deploying a Three tier web application on Azure with load balancing and VMSS

Deploying a Three tier web application on Azure with load balancing and VMSS

#10weeksofCloudOps(2/10)

Introduction

Hi Welcome to this article, My Name is Ford, I am starting to get hands on experience on DevOps and came across the 10 week cloud ops challenge posted by Piyush Sachdeva

This is week 2 of my 10weekscloudops challenge, And in this article we will deploy a three tier web application architecture on azure and as a requirement for resiliency and scalability we will use services such as load balancing and virtual machine scale sets.

This guide is beginner friendly such as deploying the web application will be installed with scripts and a couple of updating the configuration files and the rest is done in azure portal.

Pre-requisites

  • Azure Account

  • Linux terminal or Azure CLI (if using windows machine install wsl)

💡
Note: Azure Account (Free trial) - in a free trial subscription you are limited to use only 4 VCPUs

What is a three-tier architecture?

Three-tier architecture is a software design pattern that organizes applications into three distinct layers or tiers, each with its own specific function. Here's a breakdown of the three tiers:

  1. Presentation Tier: This is the user interface layer where users interact with the application. It can be a web browser, desktop application, or mobile app. The main purpose of this tier is to display information to and collect information from the user.

  2. Application Tier: Also known as the logic or middle tier, this layer processes the data collected from the presentation tier. It applies business logic, rules, and calculations. This tier acts as an intermediary between the presentation and data tiers, ensuring that data is processed correctly before being stored or displayed.

  3. Data Tier: This is where the application's data is stored, managed, and retrieved. It typically involves a database management system (DBMS) like MySQL, PostgreSQL, or MongoDB. The data tier handles all data-related operations and ensures data integrity and security.

The primary benefits of a three-tier architecture include improved scalability, maintainability, and flexibility. Each tier can be developed, updated, or scaled independently, which makes it easier to manage and adapt to changing requirement

Let’s get started

I have a github repository for this guide and on that repository we will use the Week2 subdirectory only that contains the configurations, dependencies and necessary items to make it work. but if you wish to download the whole repository you may do so.

git clone https://github.com/annoyedalien/10weekscloudchallenge.git

In case you want to download the week2 subdirectory only you may follow the commands below

#git sparse-checkout


mkdir (your directory)
cd (your directory)
git init 
git remote add -f origin https://github.com/annoyedalien/10weekscloudchallenge.git
git config core.sparseCheckout true
git sparse-checkout set Week2
git pull origin main
cd Week2

After downloading the repository, ensure that you are logged in to your azure account using az login command, because on this next step we will deploy services on azure, make sure your account has necessary permissions to create services such as:

  • Resource Group

  • Virtual Network, Public IP addresses and Subnets

  • Network Security Groups

  • Virtual Machines

  • Azure MySQL Flexible server

While on Week2 directory use ls command to show the contents and you will see a shell script name ‘deploy.sh’ on this shell script it will deploy services mentioned above.

You may also edit the script using sudo nano command if you wish to change some configuration items based on your preference such as location, names, password and etc.

sudo nano deploy.sh

Now we run the shell script to start deploying

./deploy.sh

At the start of the shell script deployment it will generate an ssh key and ask for a passphrase you may enter a passphrase for additional complexity for rsa key or you may just hit enter to leave it blank, we will use this ssh key to connect to our VMs. The ssh key will be generated on the same directory folder you are working with.

At the last part of the deployment it will ask you, if you want to create a Private DNS zone for your Azure mysql server, since our SQL server is only private it is required that is mapped to a private dns link, just type in ‘y’ and enter.

After the deployment is complete check azure portal for the resource deployed.

App-Tier Configuration

We will now connect to our VM, let’s start with the App VM with its associated public IP address, lets connect to it using ssh command and using our ssh keys.

💡
Note: The public IPs are temporary and we will just use it to have a quick access to our VMs, in the essence of security the we will use ssh keys and the NSG’s applied to the subnets are allowing SSH ports only to your public IP address.

To connect to our App VM

ssh -i host_key azureuser@<public ip of AppVM>

Once connected to the AppVM

let’s download the repository again using the sparse checkout provided at the beginning

#git sparse-checkout

After downloading navigate to Week2/backend folder

You can directly execute the shell script or make some changes by following the Optional section

./app_setup.sh

Optional: If you want to make changes first

list the items using ls command, and you may edit the following files using nano or vim according to your preference.

  • db_setup.sql - This template will create a database call ‘webappdb’ and table called “dogs” and columns ‘name’ and ‘description’

      -- Create webappdb DATABASE
      CREATE DATABASE webappdb;
    
      -- Select webappdb DATABASE
      USE webappdb;
    
      -- Create Transactions Table
      CREATE TABLE IF NOT EXISTS dogs(id INT NOT NULL
      AUTO_INCREMENT, name VARCHAR(100), description
      VARCHAR(100), PRIMARY KEY(id));    
    
      -- Insert Test Data in Table Transactions
      INSERT INTO dogs (Name,description) VALUES ('Chewy','Boy');
    
  • backendapp.js - you may change the part here if you have a different servername, password or database

      const db = mysql.createConnection({
          host: 'azure my sql hostname',
          user: 'your username',
          password: 'Your Password',
          database: 'Your database'
      });
    

in the shell script app_setup.sh you may change the mysql part depending on the sql server you have created

#!/bin/bash

sudo apt-get update
sudo apt install npm -y
sudo apt install mysql-server -y
npm install express
npm install mysql
npm install cors
npm init -y

sudo npm install -g pm2
sudo npm install
mysql -h mysql-serverdemo.mysql.database.azure.com -u mysqladmin -p <db_setup.sql

pm2 start backendapp.js
startup_as_process=$(pm2 startup | grep -o 'sudo env.*')
eval "$startup_as_process"
pm2 save

If you are wondering where to find the sql hostname you may go to azure portal and search on Azure Database for MySQL flexible servers, or type in flexible and it should show up

Click on the existing server created by the deploy.sh script and on the Overview pane you should see

After executing the app_setup.sh, let’s check if our app is working by typing:

pm2 list

you should have the following results below

in the shell script app_setup.ph there are a series of commands there that allows our application continues to run even if we exit the ssh connection and also in the event if where the VM restarts it automatically runs the backendapp.js

pm2 start backendapp.js
startup_as_process=$(pm2 startup | grep -o 'sudo env.*')
eval "$startup_as_process"
pm2 save

we can also try to check our connection to our database by typing the commands below

curl http://localhost:3000/api/dogs

This should show the example entry on the db_setup.sql which is name: Chewy and description: Boy

Now we go back to Azure portal and from there we create an image of our AppVM that will serve our VMSS

Capture Image for App-tier (App Server)

Go to Virtual Machine > Select the AppVM > on the Overview pane select Capture (Image)

Enter the necessary details and Create a New Image Gallery if necessary,

on the Target VM image definition Click on Create New

Click on Review and Create, Click Create.

💡
This process will deallocate our AppVM and an Image will be stored on the Image Gallery under Shared Images. You have the option to delete the AppVM and the associated public ip after the image creation to save on resources
💡
Take note of the process on Image capture for we will do this again later on the WebVM after the configuration.

Create Virtual Machine Scale Set (App-tier)

As part of making our architecture resilient for instances of VM failure we can have it automatically scale up based on metrics or in the event one of our VM becomes unavailable.

On Azure portal search for VMSS and Select Virtual Machine Scale Sets

Click on +Create

Enter necessary details

On Scaling Configuration, Click on default condition and you may edit these settings for autoscaling, click on save.

On the Images section, click on See all images, and the Compute Gallery will show up and select Shared Images

From the Shared images select the App-Image we have created earlier, you can see on the Administrator Account portion is greyed out because it will use the same SSH key we generated earlier.

Now click on Disks if you wish to change the Disks settings, you may skip these if you want.

On the networking tab

Select the Virtual Network and ensure you select the existing Vnet created.

On the Network Interface Select the edit (pencil) icon

Choose the App Subnet and Choose No Public IP

Let’s skip the other tabs and click on Review and Create. Once done, let’s move on to Load balancer

Create a Load balancer for App-tier

On Azure portal search for Load Balancer and select Load balancer and Click on Create

Enter necessary details

On the Frontend Ip configuration, click on Add a frontend Ip configuration

Enter necessary details, create a new public ip.

On the Backend Pools c Add a name for the Backend pool, and on Virtual Network select the existing Vnet, then on Ip configurations section click on Add, Choose the VMSS of App, Click on Save

On the Inbound Rules click on Add Load Balancing Rule

disregard the health probe on the image above and create a new one with the settings below

Click Save and proceed.

Click on Review and Create

Now we are done with the App tier, lets move on to our front end.

Configure Presentation-Tier

Connect to WebVM using ssh

ssh -i host_key azureuser@<public ip of WebVM>

Once connected to the WebVM

let’s download the repository again using the sparse checkout provided at the beginning

#git sparse-checkout

After downloading navigate to Week2/frontend directory

We need to make some changes first before running the shell script to setup our WebVM

Modify the App.js on src directory

sudo nano src/App.js

Change the section of your-app-server-ip to the Frontend IP config of your Load Balancer

Once done hit Ctrl+X to save and press ‘y’ to overwrite

Then if you are still on the frontend directory lets modify the default config for nginx that we will use later

sudo nano default

Modify the your-app-server-ip, replace with the Front end Ip configuration of the Load Balancer

Ctrl+x to save and y to overwrite.

After we made changes to App.js and default, we run the shell script

./web_setup.sh

After the installation of the required dependencies, let’s run a few more commands

#copies the modified default config to nginx directory sites-available
sudo cp default /etc/nginx/sites-available/
#makes a build folder based on the App.js and other dependencies
npm run build
#copies the finished build to the html directory
sudo cp -r build/* /var/www/html
#restarts the nginx server
sudo systemctl restart nginx

Let’s move back to Azure portal to create our application gateway

Create an Application Gateway

After the deployment of the Web VMSS, let’s create an application gateway similar to the Load balancer.

Key Differences

  • Layer of Operation: Application gateways operate at the application layer (Layer 7), while load balancers typically operate at the transport layer (Layer 4).

  • Routing Capabilities: Application gateways offer more advanced routing based on application-level data (e.g., URL paths), whereas load balancers route based on IP addresses and ports.

  • Security Features: Application gateways include features like WAF and SSL termination, which are not typically found in standard load balancers.

  • Complexity and Use Cases: Application gateways are more complex and suited for web applications needing detailed traffic management and security. Load balancers are simpler and used for distributing traffic across servers for various types of application

On Azure portal search for Application Gateway and select Application gateway.

Click on Create Application Gateway, enter the appropriate details and make sure the Virtual network uses the existing Vnet and subnet, you may choose to have multiple zones.

On Frontends create a new public ip for the Application gateway

On the Backend Pool, click on Add backend pool

Select Yes, for now.

On the Configuration tab, click on Add a routing rule

Click on Backend targets

Add new on backend setting, and Click Add

Move to Review and Create, and Create the Application Gateway

💡
While creating the application gateway you may proceed with the Image capture for the Web tier, since creating an application gateway takes more time.

Capture Image for Web-tier (Web Server)

Do the same process like we did on the AppVM, in this case you change the image name to Web-Image instead of App-Image, and also change the sku name if using the same gallery.

Create Virtual Machine Scale Set (Web-tier)

Do the same process on the App VMSS ,ensure you choose the Web-Image on the Images selection.

After deployment of the Web VMSS

Modify the Application Gateway Backend Pool and Add the VMSS for the Web server

On the Application gateway navigate to the Frontend Ip and copy the public Ip address and paste it on a browser.

This is the simple web application, it accepts the input from users such as name and description and saves it to our database with the help of application server that serves as an api to our web and database

My Experience

I just wanted to share my experience on this Week2 challenge, I would be lying if I said that I did not struggle on this challenge, I did struggle on the part where you have to create everything from scratch specially the frontend and backend applications, after creating those you have to deal with the networking side of things like ports and NSG rules. It is true that you spend more hours debugging codes and scripts on why they did not work than actually building it. I made the app as simple as I can to avoid more complexity specially for beginners.

Overall it was a fun challenge and will be moving on to the next challenge.