<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Nikhil Wilson</title>
    <description>The latest articles on Forem by Nikhil Wilson (@nikhil_wilson_dfb43fe6436).</description>
    <link>https://forem.com/nikhil_wilson_dfb43fe6436</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1733884%2F1e0eb6c6-3f3e-4f7c-8ed1-6820086f710a.png</url>
      <title>Forem: Nikhil Wilson</title>
      <link>https://forem.com/nikhil_wilson_dfb43fe6436</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/nikhil_wilson_dfb43fe6436"/>
    <language>en</language>
    <item>
      <title>3-Tier Architecture in Azure Cloud: A Comprehensive Deployment Guide</title>
      <dc:creator>Nikhil Wilson</dc:creator>
      <pubDate>Mon, 18 Nov 2024 18:01:00 +0000</pubDate>
      <link>https://forem.com/nikhil_wilson_dfb43fe6436/3-tier-architecture-in-azure-cloud-a-comprehensive-deployment-guide-5a82</link>
      <guid>https://forem.com/nikhil_wilson_dfb43fe6436/3-tier-architecture-in-azure-cloud-a-comprehensive-deployment-guide-5a82</guid>
      <description>&lt;p&gt;This project demonstrates a robust and scalable 3-tier architecture deployed in Microsoft Azure, showcasing best practices for cloud infrastructure design. A special thanks to Piyush Sachdeva for hosting the #10weeksofcloudops challenge. This blog represents my take on the second week's challenge.The architecture provides several key benefits:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;Improved Security&lt;/code&gt;: Network segmentation through subnets and network security groups&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;High Availability&lt;/code&gt;: Utilize VM scale sets and load balancers&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Scalability&lt;/code&gt;: Automatic scaling based on resource utilization&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Performance&lt;/code&gt;: Distributed application tiers with efficient traffic routing&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The architecture follows a classic 3-tier model:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5f77v7q2lo9ovm3qtgiw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5f77v7q2lo9ovm3qtgiw.png" alt="WebApp3Tier" width="800" height="302"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Web Tier&lt;/code&gt;: This is the user interface (UI) of the application. The web tier is responsible for interacting with the users and presenting the data retrieved from the app tier. In this case, it is built using React, a JavaScript library for building dynamic user interfaces. &lt;/p&gt;

&lt;p&gt;&lt;code&gt;Application Tier&lt;/code&gt;: The application tier handles business logic and data processing. It receives requests from the frontend and communicates with the database to retrieve or modify data. &lt;/p&gt;

&lt;p&gt;&lt;code&gt;Database Tier&lt;/code&gt;: The database tier is responsible for storing and retrieving the data required by the application. In this project, a MySQL database is used to store user data, application configurations, and other necessary information.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Lets start by creating a &lt;strong&gt;Resource Group&lt;/strong&gt; for provisioning of resources.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxf3vsjabvstad5med28r.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxf3vsjabvstad5med28r.png" alt="CreateResourceGroup" width="800" height="473"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create a &lt;strong&gt;Virtual Network&lt;/strong&gt; for the resource group.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa0y5wdfxfr8a3w7ojaqm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa0y5wdfxfr8a3w7ojaqm.png" alt="CreateVirtualNetwork" width="800" height="702"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create &lt;strong&gt;Subnets&lt;/strong&gt; for Web tier, App tier, and DB tier isolating the different tiers networks. Additionaly create subnets for the Bastion Host and ApplicationGateway which we will provision later. &lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Finqh1wxu4k6mhx6jk4fb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Finqh1wxu4k6mhx6jk4fb.png" alt="CreateSubnets" width="800" height="283"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create &lt;strong&gt;Network security groups&lt;/strong&gt; for the application tier, web tier and Bastion host of our architecture. We do this to add inbound security rules to control the network flow to the various tiers of the application.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs0v0pzxqhye3r7y7kiij.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs0v0pzxqhye3r7y7kiij.png" alt="NetworkSecurityGroups" width="800" height="101"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;For the Bastion Host, we provide access through SSH by allowing traffic through port 22.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fklc8v122m5ieyiaxkeg6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fklc8v122m5ieyiaxkeg6.png" alt="AddInboundRulesBastionNSG" width="800" height="1025"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Associate the Bastion NSG to the previosuly defined Bastion Subnet.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftacn5sk3bvmxil09v780.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftacn5sk3bvmxil09v780.png" alt="AssociateSubnetBastionNSG" width="800" height="424"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;For the Web network security group, we will add port 80 and port 22 in the inbound rules to allow traffic through web and ssh respectively. &lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flgh0ryun56x1nrgklqg1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flgh0ryun56x1nrgklqg1.png" alt="AddInboundRulesWebNSG" width="800" height="913"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fusznpw4z2xjh55h1sfdk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fusznpw4z2xjh55h1sfdk.png" alt="AddInboundRulesWebNSG2" width="800" height="913"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Associate the Web NSG to the Web subnet defined previously.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqw5g0rjpzti2qof7c2dw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqw5g0rjpzti2qof7c2dw.png" alt="AssociateSubnetWebNSG" width="800" height="922"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Now head to the App network security group and add port 22 for ssh access and port 4000 where our application will be listeining.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8q9hd1s2dj1dp2nx1rfh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8q9hd1s2dj1dp2nx1rfh.png" alt="InboundRulesListAppNSG" width="800" height="261"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Associate the App NSG to the App subnet created previously.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqqm1vi4a7o9lzh8af5l4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqqm1vi4a7o9lzh8af5l4.png" alt="AssociateSubnetAppNSG" width="800" height="182"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;For creating the Database server, we create the &lt;strong&gt;Azure mysql flexible server&lt;/strong&gt;. Create a unique name for the Server name option. &lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3jnaq154f9rn5hxzgu6w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3jnaq154f9rn5hxzgu6w.png" alt="DBserverCreation1" width="800" height="574"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Configure the server to choose appropriate sku for the database and also enable geo redundancy. We enable geo redundancy to provision high availability to the DB server in case of regional disruption to the servers.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyaqa6x60im41jk3bngyo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyaqa6x60im41jk3bngyo.png" alt="DBserverCreation2" width="800" height="416"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Provision a standby server by allowing high availability to the DB server.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff3ekc4t9wnfw26ie86nz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff3ekc4t9wnfw26ie86nz.png" alt="DBserverCreation3" width="800" height="479"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;In the networking tab, select private access and select the vnet and DB subnet created.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2rk5d3wsgq5bkcmf6ngw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2rk5d3wsgq5bkcmf6ngw.png" alt="DBserverCreation4" width="800" height="588"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Now we create an &lt;strong&gt;Application Gateway&lt;/strong&gt; to allow public access to our web servers and also to load balance the incoming traffic from the web.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fctdb2ta070dpij3vs18z.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fctdb2ta070dpij3vs18z.png" alt="CreateApplicationGateway1" width="800" height="611"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;In the networking tab, we provide the Application gateway subnet provisioned previously which is a requirement for the application gateway.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpwia7n14r96fiyq5dafh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpwia7n14r96fiyq5dafh.png" alt="CreateApplicationGateway2" width="800" height="205"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;For the frontend or the web tier access, let us create a public IP. From the frontend tab, create a new public IP.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fylzbw9kqo2x8bcciheaa.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fylzbw9kqo2x8bcciheaa.png" alt="CreateApplicationGateway3" width="800" height="205"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;In the backends tab, create a &lt;strong&gt;backend pool&lt;/strong&gt; without providing targets for now. We will add the IPs of the Web Virtual machines after we provision them and install the frontend code to the VM.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffiw2216zyczpu7c8cemd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffiw2216zyczpu7c8cemd.png" alt="CreateApplicationGateway4" width="800" height="325"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;From the configurations tab, we add a routing rule to the application gateway. Here we provide the Http protocol and port 80 to allow web traffic through the Application Gateway.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fej5813jwkg4akjekbhk9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fej5813jwkg4akjekbhk9.png" alt="CreateApplicationGateway5" width="800" height="692"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;In the backend targets, create a backend settings by providing the following values.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsm2jowxndsxwey62julp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsm2jowxndsxwey62julp.png" alt="CreateApplicationGateway6" width="800" height="692"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Now we create the Bastion Vm, Web VM and App Vm. Select the resource group and provision a Ubuntu image which is available.&lt;br&gt;
Here we create the Bastion VM.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fw4dhcefag9m25rppq17r.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fw4dhcefag9m25rppq17r.png" alt="CreateVM1" width="800" height="571"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Now in the networking tab, we attach the vnet and Bastion subnet which we created previously.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcqasy1gor5h6fx1dpunb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcqasy1gor5h6fx1dpunb.png" alt="VMAttachSubnet" width="800" height="571"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create the Web VM and App VM in the same format. Then attach the Web subnet and App subnet to their respective VMs.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fakgr73rbzd4p8149y0w3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fakgr73rbzd4p8149y0w3.png" alt="AllVMsDisplay" width="800" height="397"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Now we connect to the Bastion VM to access the Web VMs and App VMs for secure access. I have used a pair key value for the VMs created and have uploaded it to my azure cli. After that I have moved the key configuration to &lt;code&gt;~/.ssh/&lt;/code&gt; and run &lt;code&gt;chmod 400 'key_file_name'&lt;/code&gt;. After this access the VM by providing the key value with the ssh command.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2upp3sd7w3kpwy86u1yt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2upp3sd7w3kpwy86u1yt.png" alt="AccessBastionVM" width="800" height="218"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Now we head to create the app and web tier with our application code. SSH into the AppVM by using the private ip provisioned for the VM. I have forked the github repo by &lt;strong&gt;Nishant Singh&lt;/strong&gt; for the application code, web code, and configuration scripts. &lt;code&gt;https://github.com/thakurnishu/10_Weeks_Of_CloudOps&lt;/code&gt; and checkout to week2 branch to get the steps to implement the app backend and web frontend code and also to setup the database&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Modify the &lt;strong&gt;DBConfig.js&lt;/strong&gt; with the values respective to your mysql DB server. &lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsec2pyjk87hmw1qxmcmp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsec2pyjk87hmw1qxmcmp.png" alt="ModifyDBConfig.js" width="800" height="132"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;We also modify the server parameters to switch off &lt;code&gt;require_secure_transport&lt;/code&gt; from the mysql server menu.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhrtp5agsnoz7p67bdcic.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhrtp5agsnoz7p67bdcic.png" alt="SecureTransportOff" width="800" height="411"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Also modify the sql host and add sql admin user name in the &lt;code&gt;AppTier.sh&lt;/code&gt; config file before running the AppTier.sh script.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fo44dzpx0l36ytyt5w6m8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fo44dzpx0l36ytyt5w6m8.png" alt="AddSqlHost" width="800" height="391"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Now we run the AppTier.sh file to create the DB and also test the application. If we get response from the DB as follows, then the script ran successfully.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fumstoji1pgx2uadzzw9u.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fumstoji1pgx2uadzzw9u.png" alt="RunAppTier.sh" width="800" height="259"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Now we create an &lt;strong&gt;Internal load balancer&lt;/strong&gt; to balance the traffic from the frontend web-tier to the backend app-tier. From create a resource, name the internal load balancer and select internal as the type of load balancer.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fytdegx6s4rokcgrzrinl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fytdegx6s4rokcgrzrinl.png" alt="InternalLoadBalancer" width="800" height="701"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Now for the frontend configuration, we add the web subnet. &lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa6qht0moplk3ae3x4otk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa6qht0moplk3ae3x4otk.png" alt="InternalLoadBalancer2" width="800" height="989"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Now for the Backend pool, we add the IP configuration of the AppVM for the app-tier part.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F89s6n035spjp8euwlm32.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F89s6n035spjp8euwlm32.png" alt="InternalLoadBalancer3" width="800" height="407"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Now we add a load balancing rule where we can provide the frontend ip address and the backend pool which we created in the previous steps. We also must provide the ports for the frontend and the backend pool.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fh5g76thwgny5kd58ea2z.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fh5g76thwgny5kd58ea2z.png" alt="InternalLoadBalancer4" width="800" height="998"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Now we log out of the AppVM and connect to the WebVM from the BastionVM.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9ykb25yviebkz042t27a.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9ykb25yviebkz042t27a.png" alt="LogToWebVM" width="800" height="393"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;We fork the same repo as before and checkout week2 branch of the repo.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqcabt7615z5ran19yzax.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqcabt7615z5ran19yzax.png" alt="GitCloneWeb" width="800" height="194"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Vi into the ./webtier.sh script and replace the REPLACE-WITH-INTERNAL-LB-DNS with the ip of the internal load balancer from the overview of load balancer created previously.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmno3syt0dv58ng6o2kov.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmno3syt0dv58ng6o2kov.png" alt="AddLoadBalancerIPInScript" width="800" height="194"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Now we run the &lt;code&gt;./webtier.sh&lt;/code&gt; script which will install the necessary applications to run the frontend code and start the frontend code on the WebVM. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Now since the WebVM is up and running, we can go ahead and add the IP address of the WebVM in the ApplicationGatway in the backend pool.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fun3qa8z7awx8ekfyqeoq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fun3qa8z7awx8ekfyqeoq.png" alt="ApplicationGatewayBackendPoo" width="800" height="694"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Now from the overview of the application gateway and copy the public IP address provisioned for the application.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkrdhf1b3wxzjlo76yp5b.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkrdhf1b3wxzjlo76yp5b.png" alt="CopyPublicIP" width="800" height="407"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Run the application on any web browser by using the public IP provisioned of the application gateway.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhwgbg3lhx417atrbwor0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhwgbg3lhx417atrbwor0.png" alt="TestApp" width="800" height="475"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;We have successfully provisioned a 3 tier architecture with secure access to all the tiers. Now in order to provide high availability to our architecture, we create a VM scale sets for the web-tier and app-tier.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Now since we have the three tiers running, we can move onto create availability sets to make the web tier and app tier highly availiable for high traffic scenarios. For this we need to create VM images of the WebVM and AppVM to create availiability sets. Select the WebVM and select the capture option to create VM image.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvu3t6vj9e3q0wvf0pfsn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvu3t6vj9e3q0wvf0pfsn.png" alt="CreateVMImage" width="800" height="526"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create a compute gallery from the creation menu to store the VM image. Select specialised option so that we can get the image with all the preinstalled application which we created through the previous steps.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvjwfmk8gcuwn411hlg79.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvjwfmk8gcuwn411hlg79.png" alt="CreateVMImageGallery" width="800" height="294"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create a VM definition with the details about the VM to save.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4qc5hp6fjhvb0f04nn6j.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4qc5hp6fjhvb0f04nn6j.png" alt="CreateVMDefinition" width="800" height="737"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Repeat the same steps for AppVM and now we are ready to deploy the VM scale sets for high availiabilty. First, we create VM scale set for Web tier of the architecture. From create a virtual machine scale sets, set the name of the VM and also select multiple zones for high availity features.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fteesibijvja8yvbe8rhr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fteesibijvja8yvbe8rhr.png" alt="CreateVMScaleSets" width="800" height="640"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Select unifrom option for orchestration and keep the instance count as 2.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmvac321tzo10m7q6gacy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmvac321tzo10m7q6gacy.png" alt="CreateVMScaleSets2" width="800" height="596"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Select out previously stored VM image to deploy for the VM scale set. Also configure the scaling to automatic. Set custom scaling options to maximum of 10 instances and increment of 1 instance when CPU threshold crosses 80% for 10 minutes.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl7vyhc5e17y8bsh0kn8p.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl7vyhc5e17y8bsh0kn8p.png" alt="CreateVMScaleSets4" width="800" height="536"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;In the networking tab set the Subnet to the Web subnet and in the network interface options, edit to change the default subnet to the web subnet.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzjygphmcuo3s7gnvgjkn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzjygphmcuo3s7gnvgjkn.png" alt="CreateVMScaleSets5" width="800" height="536"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;As discussed previously, configure the scaling options according to a preset threshold criteria.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzhd714qg0z291cbb9ch6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzhd714qg0z291cbb9ch6.png" alt="CreateVMScaleSets6" width="800" height="536"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Now in the Application Gateway option, set the backend pool to now target the Web Virtual machine scale sets instead of the Web VM.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fv2kkreqda0o50jby7rkb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fv2kkreqda0o50jby7rkb.png" alt="AddBackendPoolVMSS" width="800" height="536"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;From the Web Virtual machine scales sets, select the instances and upgrade the instances to run with the latest changes by using upgrade option.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsmvlaz8h27o2r72un011.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsmvlaz8h27o2r72un011.png" alt="UpdateVMModels" width="800" height="216"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create the App virtual machine scale set using the same steps. Now head to the internal load balancer and select App Virtual machine scale sets IP configuration for the backend pool.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fackksuzlquhqmo1dd3d6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fackksuzlquhqmo1dd3d6.png" alt="AddBackendPooltoIB" width="800" height="428"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Upgrade the App virtual machine instances to run with the latest changes by using the upgrade option.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8dejyue8314vgy4j4623.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8dejyue8314vgy4j4623.png" alt="UpgradeVMModels" width="800" height="215"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That’s it! We have created a web application with a 3 tier architecuture, highly available and highly scalable. We also created network security rules to create secure access to all the application tiers. Many thanks to Nishant Singh for his &lt;a href="https://nishantsingh.hashnode.dev/10weeksofcloudops-secondweek" rel="noopener noreferrer"&gt;detail blog &lt;/a&gt;which made this project possible. Also a big shoutout to Piyush Sachdeva's 10weeksofcloudops challenge. Please check out his &lt;a href="https://www.youtube.com/playlist?list=PLl4APkPHzsUUc8HOEIwfB3Z2uxRv2SKOG" rel="noopener noreferrer"&gt;youtube channel&lt;/a&gt; for some amazing cloud tech content.&lt;/p&gt;

</description>
      <category>azure</category>
      <category>cloud</category>
      <category>architecture</category>
    </item>
    <item>
      <title>Hosting a Static Website in Azure Storage with CDN and CI/CD Pipeline Integration</title>
      <dc:creator>Nikhil Wilson</dc:creator>
      <pubDate>Sat, 16 Nov 2024 08:45:38 +0000</pubDate>
      <link>https://forem.com/nikhil_wilson_dfb43fe6436/hosting-a-static-website-in-azure-storage-with-cdn-and-cicd-pipeline-integration-20b6</link>
      <guid>https://forem.com/nikhil_wilson_dfb43fe6436/hosting-a-static-website-in-azure-storage-with-cdn-and-cicd-pipeline-integration-20b6</guid>
      <description>&lt;p&gt;In this blog post, we will explore how to:  &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Host a static website in an Azure storage container.
&lt;/li&gt;
&lt;li&gt;Create a CDN endpoint for the static website.
&lt;/li&gt;
&lt;li&gt;Connect a custom domain to the CDN endpoint.
&lt;/li&gt;
&lt;li&gt;Utilize Azure DevOps to implement CI/CD pipelines.
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;A special thanks to Piyush Sachdeva for hosting the #10weeksofcloudops challenge. This blog represents my take on the first week's challenge.  &lt;/p&gt;




&lt;h2&gt;
  
  
  Architecture Overview
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq1gtay5kfhj5ar7h89jg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq1gtay5kfhj5ar7h89jg.png" alt="Architecture diagram" width="800" height="360"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 1: Create a Resource Group
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Search for &lt;strong&gt;Resource Group&lt;/strong&gt; in the "Create a Resource" menu.&lt;br&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmvz9natx340j6roqa2e6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmvz9natx340j6roqa2e6.png" alt="Resource Group store" width="800" height="410"&gt;&lt;/a&gt;  &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create a resource group under the required subscription.&lt;br&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fenltp5ni04f1hd24v4on.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fenltp5ni04f1hd24v4on.png" alt="Resource group create" width="800" height="410"&gt;&lt;/a&gt;  &lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Step 2: Create a Storage Account
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;From the "Create a Resource" menu, search for &lt;strong&gt;Storage Account&lt;/strong&gt;.&lt;br&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6aselabvo6x3qf1v3dg0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6aselabvo6x3qf1v3dg0.png" alt="Storage account store" width="800" height="410"&gt;&lt;/a&gt;  &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create a storage account under the same subscription and select the resource group from the dropdown menu.&lt;br&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl3a5bjl0g26tb8k1z12f.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl3a5bjl0g26tb8k1z12f.png" alt="Storage account create" width="800" height="410"&gt;&lt;/a&gt;  &lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Step 3: Enable Static Website Hosting
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Navigate to the &lt;strong&gt;Overview&lt;/strong&gt; section of your storage account and click on &lt;strong&gt;Static Website&lt;/strong&gt; under the capabilities section.&lt;br&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fshbvdrg6odrcclwxknrk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fshbvdrg6odrcclwxknrk.png" alt="Static website capability" width="800" height="407"&gt;&lt;/a&gt;  &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Enable the &lt;strong&gt;Static Website&lt;/strong&gt; option and specify the names of your &lt;code&gt;index.html&lt;/code&gt; and &lt;code&gt;error.html&lt;/code&gt; files.&lt;br&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fx8u0gv4wetltfcxltit4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fx8u0gv4wetltfcxltit4.png" alt="Static website enable" width="800" height="407"&gt;&lt;/a&gt;  &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Upload the required HTML files to the &lt;code&gt;$web&lt;/code&gt; container.&lt;br&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3qjadzrxgh2pnzb3owa5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3qjadzrxgh2pnzb3owa5.png" alt="Upload html files" width="800" height="407"&gt;&lt;/a&gt;  &lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Step 4: Create a CDN Profile
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Search for &lt;strong&gt;Front Door and CDN Profiles&lt;/strong&gt; in the "Create a Resource" menu.&lt;br&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flvmcgylb04uzunrii7l6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flvmcgylb04uzunrii7l6.png" alt="Cdn store" width="800" height="428"&gt;&lt;/a&gt;  &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Select &lt;strong&gt;Azure CDN&lt;/strong&gt;.  &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: Azure CDN is not available for free or student subscriptions. Upgrade to a &lt;strong&gt;Pay-As-You-Go&lt;/strong&gt; subscription or another eligible plan.&lt;br&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fudg93komind2wkwym4dz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fudg93komind2wkwym4dz.png" alt="Cdn compare options" width="800" height="428"&gt;&lt;/a&gt;  &lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create the CDN profile in the same resource group, keeping the default settings.&lt;br&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzbrz6jkc7pybhpbyb9vo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzbrz6jkc7pybhpbyb9vo.png" alt="CDN create" width="800" height="428"&gt;&lt;/a&gt;  &lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Step 5: Create a CDN Endpoint
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Navigate to the &lt;strong&gt;Endpoint Creation&lt;/strong&gt; button in your CDN profile.&lt;br&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqpyz39h86i0u5x9b61gn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqpyz39h86i0u5x9b61gn.png" alt="Endpoint option" width="800" height="428"&gt;&lt;/a&gt;  &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create an endpoint, selecting &lt;strong&gt;Storage Static Website&lt;/strong&gt; as the origin type. The static website name will populate automatically.&lt;br&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxq874fhyyxp8ud7k3blk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxq874fhyyxp8ud7k3blk.png" alt="Endpoint create" width="800" height="428"&gt;&lt;/a&gt;  &lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Step 6: Connect a Custom Domain
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;If you’ve purchased a custom domain (e.g., from Namecheap.com), log in to your registrar's dashboard.  &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Under the &lt;strong&gt;Advanced DNS&lt;/strong&gt; tab of your domain, add two &lt;strong&gt;CNAME&lt;/strong&gt; records:  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Type&lt;/strong&gt;: &lt;code&gt;CNAME&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Host&lt;/strong&gt;: &lt;code&gt;https&lt;/code&gt; and &lt;code&gt;www&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Value&lt;/strong&gt;: The CDN endpoint name
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;TTL&lt;/strong&gt;: &lt;code&gt;Automatic&lt;/code&gt;
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F56ovgrmj7854ksoxs2ix.png" alt="CNAME from domain" width="800" height="179"&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Go back to your CDN profile in Azure and add the custom domain. Azure will verify the DNS records.&lt;br&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl5ycsg8zuoe7lt4156k7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl5ycsg8zuoe7lt4156k7.png" alt="Link custom domain with endpoint" width="800" height="426"&gt;&lt;/a&gt;  &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Enable HTTPS for your custom domain in the CDN settings.&lt;br&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4uuhlah854wl07hkb08f.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4uuhlah854wl07hkb08f.png" alt="Enable https for endpoint" width="800" height="558"&gt;&lt;/a&gt;  &lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Congratulations! You’ve successfully hosted a static website in Azure and linked it to a custom domain.  &lt;/p&gt;




&lt;h2&gt;
  
  
  Step 7: Implement CI/CD Using Azure DevOps
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Create a new project in Azure DevOps.&lt;br&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhmukwf8hiulpb50blekh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhmukwf8hiulpb50blekh.png" alt="Create project" width="800" height="586"&gt;&lt;/a&gt;  &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Navigate to &lt;strong&gt;Project Settings&lt;/strong&gt; &amp;gt; &lt;strong&gt;Agent Pools&lt;/strong&gt; and create a new agent pool.&lt;br&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqv2wsnlkvddagtu3xxhv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqv2wsnlkvddagtu3xxhv.png" alt="Agent pool" width="558" height="1526"&gt;&lt;/a&gt;  &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Download the appropriate agent for your local machine and follow the setup instructions.&lt;br&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkt5w2nuar2mz3elqxted.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkt5w2nuar2mz3elqxted.png" alt="Get the agent" width="800" height="779"&gt;&lt;/a&gt;  &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Generate a &lt;strong&gt;Personal Access Token (PAT)&lt;/strong&gt; under &lt;strong&gt;User Settings&lt;/strong&gt; with necessary permissions. Use the PAT to configure the agent during setup.&lt;br&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp9rtvad242nrpkzcx0rg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp9rtvad242nrpkzcx0rg.png" alt="Select scope create" width="800" height="594"&gt;&lt;/a&gt;  &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Start the agent using &lt;code&gt;./run.sh&lt;/code&gt;. It will begin listening for jobs.&lt;br&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb45mscc1gmhgo671ai6d.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb45mscc1gmhgo671ai6d.png" alt="Run the agent" width="800" height="66"&gt;&lt;/a&gt;  &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create a new &lt;strong&gt;Service Connection&lt;/strong&gt; under &lt;strong&gt;Project Settings&lt;/strong&gt; and link it to your Azure subscription and resource group. Now if your browser disables popups automatically, please disable them for this step because resource group will not be seen until you authenticate again during this step.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fks1ji8qsb8ol57bgalvz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fks1ji8qsb8ol57bgalvz.png" alt="Create service connection" width="800" height="1317"&gt;&lt;/a&gt;  &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Now we need to configure the CI/CD pipelines and we use the following azure-pipeline.yml file to configure it.&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;trigger:
- main

pool: Default

steps:
- task: AzureCLI@2
  displayName: 'Running Pipeline Script'
  inputs:
    azureSubscription: 'StaticWebsite'
    scriptType: 'bash'
    scriptLocation: 'scriptPath'
    scriptPath: 'pipeline_script.sh'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here the trigger option refers to the github branch of the static website code repo. pool refers to the agent pool which is running in your machine. The azureSubscription refers to the service connection name which is defined earlier while creating a new service connection. Now this script runs the pipeline_script.sh file which is defined as follows.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#!/bin/bash

AccountName="personalwebsitestorage"
RG="PersonalWebsiteRG"
ProfileName="PersonalWebsiteCDN"
EndPoint="PersonalWebsiteEndpoint"

echo "--------------------------------------------------------"
echo "|   Removing previous content from CDN edge locations  |"
echo "--------------------------------------------------------"

az cdn endpoint purge \
      --name $EndPoint \
      --profile-name $ProfileName \
      --resource-group $RG \
      --content-paths "/*"


echo "--------------------------------------------------------"
echo "|           Uploading to Azure Storage Account         |"
echo "--------------------------------------------------------"

Connection_String=$(az storage account show-connection-string --name $AccountName --resource-group $RG --query connectionString -o tsv)
az storage blob upload-batch \
  -d "\$web" \
  -s "website" \
  --connection-string $Connection_String \
  --overwrite \
  --pattern "*"

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here modify the AccountName to the storage account name where the static website is hosted. In RG section, give the resource group name with which we work with. In the ProfileName section, provide the name of the CDN profile created and for EndPoint, give the name of the CDN endpoint created under the profile. &lt;/p&gt;

&lt;p&gt;This script first purges all the cached data on the CDN edge locations and then uploads the new content to the storage account which will modify our static website through the pipeline.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Now let us setup the pipeline in Azure Devops portal. Select the project and head to the pipelines section. Create a new pipeline and select Github option.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgjtbzxe1tzygm97dv49q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgjtbzxe1tzygm97dv49q.png" alt="Azure pipeline menu" width="800" height="498"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Now select the github repo corresponding to the static website and select the existing azure pipeline yaml file option. Review the yaml file &lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2ngtmny3zod3prvg7zmi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2ngtmny3zod3prvg7zmi.png" alt="yaml file selection" width="800" height="1093"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Verify the branch of the github repo and the filename of the pipeline and run the pipeline.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F688lyn3cnkl4q7s7waxk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F688lyn3cnkl4q7s7waxk.png" alt="branch and yaml filename verify" width="800" height="461"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Now the CI/CD pipleine is successfully setup.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk8bwh8futfer9mijcctt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk8bwh8futfer9mijcctt.png" alt="Run log" width="800" height="508"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That’s it! You’ve successfully set up a static website with Azure Storage, integrated Azure CDN, linked a custom domain, and implemented a CI/CD pipeline with Azure DevOps. A special thanks to Nishant Singh for his detail &lt;a href="https://nishantsingh.hashnode.dev/10weeksofcloudops-firstweek" rel="noopener noreferrer"&gt;blog&lt;/a&gt; which helped immensely to create this project. Also a big shoutout to Piyush Sachdeva's 10weeksofcloudops challenge. Please check out his &lt;a href="https://www.youtube.com/@TechTutorialswithPiyush" rel="noopener noreferrer"&gt;youtube channel&lt;/a&gt; for some amazing cloud tech content.&lt;/p&gt;

</description>
      <category>devops</category>
      <category>azure</category>
      <category>staticwebsite</category>
      <category>cicd</category>
    </item>
    <item>
      <title>Docker fundamentals</title>
      <dc:creator>Nikhil Wilson</dc:creator>
      <pubDate>Wed, 18 Sep 2024 08:17:21 +0000</pubDate>
      <link>https://forem.com/nikhil_wilson_dfb43fe6436/docker-fundamentals-59c4</link>
      <guid>https://forem.com/nikhil_wilson_dfb43fe6436/docker-fundamentals-59c4</guid>
      <description>&lt;p&gt;This is Task 1/40 of the Certified Kubernetes Administrator(CKA) 2024 video series by Piyush Sachdeva. &lt;a href="https://youtube.com/@techtutorialswithpiyush" rel="noopener noreferrer"&gt;Tech Tutorials with Piyush&lt;/a&gt;&lt;br&gt;
Video from Day 1 for Docker tutorials for Beginners &lt;iframe width="710" height="399" src="https://www.youtube.com/embed/ul96dslvVwY"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;Docker is an open-source tool that containerizes an entire application along with its dependencies, codebase, and even the underlying operating system. Users can define a Dockerfile specifying all the necessary build requirements, pass it to the Docker daemon, and create an image of the application. This image can then be shared with others, who can simply run it to obtain a fully operational container. No more hassles with installation, fixing dependencies, or meeting other prerequisites.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Here’s a simple use case:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Imagine you're building a web application using Node.js v16.20.2 and React v16.10.1. You’ve used npm to install all the required dependencies based on the framework. Everything works fine until you share it with a friend for testing. Now your friend needs to set up a virtual machine and install the necessary frameworks and packages, or reinstall Node.js, React, and npm to match your environment. That’s time wasted—time that could be spent testing the application!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2rynzo4xi4319fgjqnnr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2rynzo4xi4319fgjqnnr.png" alt="simple docker workflow" width="800" height="341"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Instead, you can create a Dockerfile that handles the installation of dependencies, copies the codebase, and exposes the application’s port. After building the image, you can upload it to a registry like Docker Hub. The tester can then pull the image, run it to create a container, and—just like that—the web application is up and running for testing. This ensures that the development, testing, and production teams are all working with the same image, resolving the infamous "it works on my machine" issue.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Let’s also take a look at Docker's architecture:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg5vw8gw4jp96v2e50q5j.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg5vw8gw4jp96v2e50q5j.png" alt="docker architecture" width="800" height="386"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The user defines a Dockerfile with all the necessary build requirements.&lt;/li&gt;
&lt;li&gt;The Docker daemon (Dockerd) uses the Dockerfile to build an image of the application with the &lt;code&gt;docker build&lt;/code&gt; command.&lt;/li&gt;
&lt;li&gt;With the &lt;code&gt;docker push&lt;/code&gt; command, the image is uploaded to a Docker image registry, such as Docker Hub, where it can be versioned and tracked.&lt;/li&gt;
&lt;li&gt;Users can then download the image from the registry using the &lt;code&gt;docker pull&lt;/code&gt; command.&lt;/li&gt;
&lt;li&gt;Finally, a container is created from the image using the &lt;code&gt;docker run&lt;/code&gt; command, and the application is ready to use.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In summary, Docker simplifies the entire process of application development, testing, and deployment by packaging everything into a single image that can be shared and run anywhere. With Docker, you eliminate the frustrating "works on my machine" issue and ensure that all teams—whether in development, testing, or production—are using the same environment.&lt;/p&gt;

</description>
      <category>docker</category>
      <category>devops</category>
      <category>40daysofkubernetes</category>
      <category>kubernetes</category>
    </item>
  </channel>
</rss>
