<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>App Services &#8211; Blog of Kliment Andreev &#8211; A place so I won&#039;t forget things</title>
	<atom:link href="https://blog.andreev.it/tag/app-services/feed/" rel="self" type="application/rss+xml" />
	<link>https://blog.andreev.it</link>
	<description></description>
	<lastBuildDate>Sun, 16 Jan 2022 22:45:54 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	
	<item>
		<title>Azure: Azure App Services &#8211; High Availability</title>
		<link>https://blog.andreev.it/2022/01/azure-azure-app-services-high-availability/</link>
					<comments>https://blog.andreev.it/2022/01/azure-azure-app-services-high-availability/#respond</comments>
		
		<dc:creator><![CDATA[Kliment Andreev]]></dc:creator>
		<pubDate>Fri, 07 Jan 2022 17:55:47 +0000</pubDate>
				<category><![CDATA[Azure]]></category>
		<category><![CDATA[Cloud]]></category>
		<category><![CDATA[App Services]]></category>
		<category><![CDATA[HA]]></category>
		<category><![CDATA[High Availability]]></category>
		<category><![CDATA[WebApp]]></category>
		<guid isPermaLink="false">https://blog.andreev.it/?p=9030</guid>

					<description><![CDATA[In this post I&#8217;ll describe how to have a HA web app in Azure&#8230;]]></description>
										<content:encoded><![CDATA[<div id="bsf_rt_marker"></div><p>In this post I&#8217;ll describe how to have a HA web app in Azure using <strong>Azure App Services</strong>. Currently, you can&#8217;t create an HA web app from the portal and you have to use an ARM template. It&#8217;s actually an HA config for the <strong>App Service Plan</strong>, not the <strong>App Service</strong>. So, in order to create an HA Web App, we&#8217;ll create an HA App Service Plan using ARM template and then create the app from the portal. Then, we&#8217;ll put the app behind an App Gateway. You can check this <a href="https://docs.microsoft.com/en-us/azure/app-service/how-to-zone-redundancy" rel="noopener" target="_blank">link</a> for more info on HA for the App Service Plan.<br />
There are two ways to accomplish this. An Azure App with a service endpoint and with a private endpoint. With the service endpoint, the App will have a public IP, but you can still restrict the access from the App Gateway. This case doesn&#8217;t require a VNET. The second option is to use a private endpoint. In this case, you&#8217;ll need a dedicated VNET, but your app won&#8217;t have a public IP. Actually, there will be a public URL, but it won&#8217;t be accessible. This dedicated VNET can be used for Azure Apps only. We&#8217;ll go with this scenario using a web app and a MySQL server (this is optional).</p>
<h1>Resource group</h1>
<p>Create a resource group in some subscription and name it. In my case I&#8217;ll name my <strong>rgWebAppHA</strong>. </p>
<h1>Virtual Network (VNET)</h1>
<p>Create a new VNET called <strong>vnetWebAppHA</strong> (/22) with 4 subnets (/24). Name the subnets: <strong>subGW, subApp</strong>, <strong>subDB</strong> and <strong>subPE</strong>. In my case, I&#8217;ll choose <strong>192.168.100.0/22</strong> for the VNET CIDR and <strong>192.168.100/101/102/103/.0/24</strong> for <strong>subGW, SubApp</strong>, <strong>subDB</strong> and <strong>subPE</strong> respectively.<br />
<a href="https://blog.andreev.it/wp-content/uploads/2022/01/P158-13.png"><img fetchpriority="high" decoding="async" src="https://blog.andreev.it/wp-content/uploads/2022/01/P158-13.png" alt="" width="1506" height="966" class="aligncenter size-full wp-image-9065" /></a></p>
<h1>App Service Plan</h1>
<p>You will need Azure CLI to be able to deploy an ARM template. From Azure CLI, log to Azure and set the default subscription where you created your resource group.</p>
<pre class="brush: bash; title: ; notranslate">
az login
az account set --subscription &lt;name or id&gt;
</pre>
<p>Now, you can create the App Service Plan using ARM. Copy and paste these two files. Name the first one <strong>deploy.json</strong> and the second as <strong>deploy.params.json</strong>.</p>
<pre class="brush: xml; collapse: true; light: false; title: ; toolbar: true; notranslate">
{
    &quot;$schema&quot;: &quot;https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#&quot;,
    &quot;contentVersion&quot;: &quot;1.0.0.0&quot;,
    &quot;parameters&quot;: {
        &quot;asp_name&quot;: {
            &quot;type&quot;: &quot;String&quot;
        },
        &quot;loc_name&quot;: {
            &quot;type&quot;: &quot;String&quot;
        }
    },
    &quot;variables&quot;: {},
    &quot;resources&quot;: &#x5B;
        {
            &quot;type&quot;: &quot;Microsoft.Web/serverfarms&quot;,
            &quot;apiVersion&quot;: &quot;2021-02-01&quot;,
            &quot;name&quot;: &quot;&#x5B;parameters('asp_name')]&quot;,
            &quot;location&quot;: &quot;&#x5B;parameters('loc_name')]&quot;,
            &quot;sku&quot;: {
                &quot;name&quot;: &quot;P1v2&quot;,
                &quot;tier&quot;: &quot;PremiumV2&quot;,
                &quot;size&quot;: &quot;P1v2&quot;,
                &quot;family&quot;: &quot;Pv2&quot;,
                &quot;capacity&quot;: 3
            },
            &quot;kind&quot;: &quot;linux&quot;,
            &quot;properties&quot;: {
                &quot;perSiteScaling&quot;: false,
                &quot;elasticScaleEnabled&quot;: false,
                &quot;maximumElasticWorkerCount&quot;: 1,
                &quot;isSpot&quot;: false,
                &quot;reserved&quot;: true,
                &quot;isXenon&quot;: false,
                &quot;hyperV&quot;: false,
                &quot;targetWorkerCount&quot;: 0,
                &quot;targetWorkerSizeId&quot;: 0,
                &quot;zoneRedundant&quot;: true
            }
        }
    ]
}
</pre>
<p>The params file. </p>
<pre class="brush: xml; highlight: [6,9]; title: ; notranslate">
{
  &quot;$schema&quot;: &quot;https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#&quot;,
  &quot;contentVersion&quot;: &quot;1.0.0.0&quot;,
  &quot;parameters&quot;: {
    &quot;asp_name&quot;: {
      &quot;value&quot;: &quot;aspWebAppHA&quot;
    },
    &quot;loc_name&quot;: {
      &quot;value&quot;: &quot;East US&quot;
    }
  }
}
</pre>
<p>Change the values in lines 6 and 9 to suit your needs. Line 6 is the name of the service plan and line 9 specifies the location. Once completed deploy the ARM template.</p>
<pre class="brush: bash; title: ; notranslate">
az deployment group create --name depWebAppHA --resource-group rgWebAppHA --template-file deploy.json --parameters deploy.params.json
</pre>
<p>If everything is OK, you&#8217;ll see Succeeded code in the output. </p>
<pre class="brush: xml; title: ; notranslate">
  &quot;provisioningState&quot;: &quot;Succeeded&quot;,
    &quot;templateHash&quot;: &quot;6541057887484946146&quot;,
    &quot;templateLink&quot;: null,
    &quot;timestamp&quot;: &quot;2021-12-09T21:07:41.083656+00:00&quot;,
    &quot;validatedResources&quot;: null
</pre>
<p>If you click on the <strong>Overview</strong> for the App Service plan, you&#8217;ll see that Zone redundant is enabled.<br />
<a href="https://blog.andreev.it/wp-content/uploads/2021/12/P158-02.png"><img decoding="async" src="https://blog.andreev.it/wp-content/uploads/2021/12/P158-02.png" alt="" width="2040" height="386" class="aligncenter size-full wp-image-9038" srcset="https://blog.andreev.it/wp-content/uploads/2021/12/P158-02.png 2040w, https://blog.andreev.it/wp-content/uploads/2021/12/P158-02-300x57.png 300w, https://blog.andreev.it/wp-content/uploads/2021/12/P158-02-1024x194.png 1024w, https://blog.andreev.it/wp-content/uploads/2021/12/P158-02-768x145.png 768w, https://blog.andreev.it/wp-content/uploads/2021/12/P158-02-1536x291.png 1536w, https://blog.andreev.it/wp-content/uploads/2021/12/P158-02-1920x363.png 1920w, https://blog.andreev.it/wp-content/uploads/2021/12/P158-02-1170x221.png 1170w, https://blog.andreev.it/wp-content/uploads/2021/12/P158-02-585x111.png 585w" sizes="(max-width: 2040px) 100vw, 2040px" /></a></p>
<h1>App Services</h1>
<p>Now that you have the plan ready, it&#8217;s time to create the web app. Go to <strong>App Services</strong> and create a new one. In my case, it looks like this. Notice at the bottom that I am using the app service plan that we just created. We&#8217;ll use Linux instance and PHP 7.4.<br />
<a href="https://blog.andreev.it/wp-content/uploads/2021/12/P158-01.png"><img decoding="async" src="https://blog.andreev.it/wp-content/uploads/2021/12/P158-01.png" alt="" width="1590" height="1498" class="aligncenter size-full wp-image-9037" srcset="https://blog.andreev.it/wp-content/uploads/2021/12/P158-01.png 1590w, https://blog.andreev.it/wp-content/uploads/2021/12/P158-01-300x283.png 300w, https://blog.andreev.it/wp-content/uploads/2021/12/P158-01-1024x965.png 1024w, https://blog.andreev.it/wp-content/uploads/2021/12/P158-01-768x724.png 768w, https://blog.andreev.it/wp-content/uploads/2021/12/P158-01-1536x1447.png 1536w, https://blog.andreev.it/wp-content/uploads/2021/12/P158-01-1170x1102.png 1170w, https://blog.andreev.it/wp-content/uploads/2021/12/P158-01-585x551.png 585w" sizes="(max-width: 1590px) 100vw, 1590px" /></a><br />
Once the app is created, click on the <strong>Overview</strong> and you&#8217;ll see the URL for the app. You&#8217;ll get some generic web page if you click on the URL.<br />
<a href="https://blog.andreev.it/wp-content/uploads/2021/12/P158-03.png"><img loading="lazy" decoding="async" src="https://blog.andreev.it/wp-content/uploads/2021/12/P158-03.png" alt="" width="2670" height="424" class="aligncenter size-full wp-image-9040" srcset="https://blog.andreev.it/wp-content/uploads/2021/12/P158-03.png 2670w, https://blog.andreev.it/wp-content/uploads/2021/12/P158-03-300x48.png 300w, https://blog.andreev.it/wp-content/uploads/2021/12/P158-03-1024x163.png 1024w, https://blog.andreev.it/wp-content/uploads/2021/12/P158-03-768x122.png 768w, https://blog.andreev.it/wp-content/uploads/2021/12/P158-03-1536x244.png 1536w, https://blog.andreev.it/wp-content/uploads/2021/12/P158-03-2048x325.png 2048w, https://blog.andreev.it/wp-content/uploads/2021/12/P158-03-1920x305.png 1920w, https://blog.andreev.it/wp-content/uploads/2021/12/P158-03-1170x186.png 1170w, https://blog.andreev.it/wp-content/uploads/2021/12/P158-03-585x93.png 585w" sizes="(max-width: 2670px) 100vw, 2670px" /></a><br />
On the left side, under <strong>Development Tools</strong>, click on <strong>SSH</strong> and it will open up a new browser window with SSH access.<br />
<a href="https://blog.andreev.it/wp-content/uploads/2021/12/P158-04.png"><img loading="lazy" decoding="async" src="https://blog.andreev.it/wp-content/uploads/2021/12/P158-04.png" alt="" width="858" height="784" class="aligncenter size-full wp-image-9039" srcset="https://blog.andreev.it/wp-content/uploads/2021/12/P158-04.png 858w, https://blog.andreev.it/wp-content/uploads/2021/12/P158-04-300x274.png 300w, https://blog.andreev.it/wp-content/uploads/2021/12/P158-04-768x702.png 768w, https://blog.andreev.it/wp-content/uploads/2021/12/P158-04-585x535.png 585w" sizes="(max-width: 858px) 100vw, 858px" /></a><br />
Once there, run this command that. It creates an <strong>index.php</strong> file that gives you all info about the webserver, PHP and PHP modules.</p>
<pre class="brush: bash; title: ; notranslate">
echo &quot;&lt;?php phpinfo(); ?&gt;&quot; &gt; /home/site/wwwroot/index.php
</pre>
<p>If you go to the URL of your site again, instead of the generic page, you&#8217;ll see something like this&#8230;plus more.<br />
<a href="https://blog.andreev.it/wp-content/uploads/2021/12/P158-05.png"><img loading="lazy" decoding="async" src="https://blog.andreev.it/wp-content/uploads/2021/12/P158-05.png" alt="" width="1894" height="656" class="aligncenter size-full wp-image-9045" srcset="https://blog.andreev.it/wp-content/uploads/2021/12/P158-05.png 1894w, https://blog.andreev.it/wp-content/uploads/2021/12/P158-05-300x104.png 300w, https://blog.andreev.it/wp-content/uploads/2021/12/P158-05-1024x355.png 1024w, https://blog.andreev.it/wp-content/uploads/2021/12/P158-05-768x266.png 768w, https://blog.andreev.it/wp-content/uploads/2021/12/P158-05-1536x532.png 1536w, https://blog.andreev.it/wp-content/uploads/2021/12/P158-05-1170x405.png 1170w, https://blog.andreev.it/wp-content/uploads/2021/12/P158-05-585x203.png 585w" sizes="(max-width: 1894px) 100vw, 1894px" /></a></p>
<h1>Application Gateway</h1>
<p>Let&#8217;s provision the application gateway. In my case, the first screen looks like this. I&#8217;ll name the gateway <strong>agwWebAppHA</strong> and I&#8217;ll use the subnet <strong>subGW</strong> for it. For the availability zone, choose all three.<br />
<a href="https://blog.andreev.it/wp-content/uploads/2022/01/P158-06.png"><img loading="lazy" decoding="async" src="https://blog.andreev.it/wp-content/uploads/2022/01/P158-06.png" alt="" width="1660" height="1324" class="aligncenter size-full wp-image-9054" srcset="https://blog.andreev.it/wp-content/uploads/2022/01/P158-06.png 1660w, https://blog.andreev.it/wp-content/uploads/2022/01/P158-06-300x239.png 300w, https://blog.andreev.it/wp-content/uploads/2022/01/P158-06-1024x817.png 1024w, https://blog.andreev.it/wp-content/uploads/2022/01/P158-06-768x613.png 768w, https://blog.andreev.it/wp-content/uploads/2022/01/P158-06-1536x1225.png 1536w, https://blog.andreev.it/wp-content/uploads/2022/01/P158-06-1170x933.png 1170w, https://blog.andreev.it/wp-content/uploads/2022/01/P158-06-585x467.png 585w" sizes="(max-width: 1660px) 100vw, 1660px" /></a><br />
Create a new public IP for the gateway.<br />
<a href="https://blog.andreev.it/wp-content/uploads/2022/01/P158-07.png"><img loading="lazy" decoding="async" src="https://blog.andreev.it/wp-content/uploads/2022/01/P158-07.png" alt="" width="1316" height="1022" class="aligncenter size-full wp-image-9055" srcset="https://blog.andreev.it/wp-content/uploads/2022/01/P158-07.png 1316w, https://blog.andreev.it/wp-content/uploads/2022/01/P158-07-300x233.png 300w, https://blog.andreev.it/wp-content/uploads/2022/01/P158-07-1024x795.png 1024w, https://blog.andreev.it/wp-content/uploads/2022/01/P158-07-768x596.png 768w, https://blog.andreev.it/wp-content/uploads/2022/01/P158-07-1170x909.png 1170w, https://blog.andreev.it/wp-content/uploads/2022/01/P158-07-585x454.png 585w" sizes="(max-width: 1316px) 100vw, 1316px" /></a><br />
Add a new <strong>backend pool</strong> but click on <strong>Yes</strong> to add the backend pool without the targets.<br />
<a href="https://blog.andreev.it/wp-content/uploads/2022/01/P158-08.png"><img loading="lazy" decoding="async" src="https://blog.andreev.it/wp-content/uploads/2022/01/P158-08.png" alt="" width="1146" height="744" class="aligncenter size-full wp-image-9056" /></a><br />
Click on <strong>Add a routing rule</strong>.<br />
<a href="https://blog.andreev.it/wp-content/uploads/2022/01/P158-09.png"><img loading="lazy" decoding="async" src="https://blog.andreev.it/wp-content/uploads/2022/01/P158-09.png" alt="" width="2798" height="530" class="aligncenter size-full wp-image-9057" srcset="https://blog.andreev.it/wp-content/uploads/2022/01/P158-09.png 2798w, https://blog.andreev.it/wp-content/uploads/2022/01/P158-09-300x57.png 300w, https://blog.andreev.it/wp-content/uploads/2022/01/P158-09-1024x194.png 1024w, https://blog.andreev.it/wp-content/uploads/2022/01/P158-09-768x145.png 768w, https://blog.andreev.it/wp-content/uploads/2022/01/P158-09-1536x291.png 1536w, https://blog.andreev.it/wp-content/uploads/2022/01/P158-09-2048x388.png 2048w, https://blog.andreev.it/wp-content/uploads/2022/01/P158-09-1920x364.png 1920w, https://blog.andreev.it/wp-content/uploads/2022/01/P158-09-1170x222.png 1170w, https://blog.andreev.it/wp-content/uploads/2022/01/P158-09-585x111.png 585w" sizes="(max-width: 2798px) 100vw, 2798px" /></a><br />
Create a new rule and a listener as described. Don&#8217;t click add after. There is another tab.<br />
<a href="https://blog.andreev.it/wp-content/uploads/2022/01/P158-10.png"><img loading="lazy" decoding="async" src="https://blog.andreev.it/wp-content/uploads/2022/01/P158-10.png" alt="" width="1664" height="956" class="aligncenter size-full wp-image-9058" srcset="https://blog.andreev.it/wp-content/uploads/2022/01/P158-10.png 1664w, https://blog.andreev.it/wp-content/uploads/2022/01/P158-10-300x172.png 300w, https://blog.andreev.it/wp-content/uploads/2022/01/P158-10-1024x588.png 1024w, https://blog.andreev.it/wp-content/uploads/2022/01/P158-10-768x441.png 768w, https://blog.andreev.it/wp-content/uploads/2022/01/P158-10-1536x882.png 1536w, https://blog.andreev.it/wp-content/uploads/2022/01/P158-10-1170x672.png 1170w, https://blog.andreev.it/wp-content/uploads/2022/01/P158-10-585x336.png 585w" sizes="(max-width: 1664px) 100vw, 1664px" /></a><br />
Click on the second tab <strong>Backend targets</strong> after. Choose the backend target that we created from the dropdown. For HTTP settings, click to <strong>Add new</strong>. Make sure you change the settings as below for the host headers.<br />
<a href="https://blog.andreev.it/wp-content/uploads/2022/01/P158-11.png"><img loading="lazy" decoding="async" src="https://blog.andreev.it/wp-content/uploads/2022/01/P158-11.png" alt="" width="1660" height="994" class="aligncenter size-full wp-image-9059" srcset="https://blog.andreev.it/wp-content/uploads/2022/01/P158-11.png 1660w, https://blog.andreev.it/wp-content/uploads/2022/01/P158-11-300x180.png 300w, https://blog.andreev.it/wp-content/uploads/2022/01/P158-11-1024x613.png 1024w, https://blog.andreev.it/wp-content/uploads/2022/01/P158-11-768x460.png 768w, https://blog.andreev.it/wp-content/uploads/2022/01/P158-11-1536x920.png 1536w, https://blog.andreev.it/wp-content/uploads/2022/01/P158-11-1170x701.png 1170w, https://blog.andreev.it/wp-content/uploads/2022/01/P158-11-585x350.png 585w" sizes="(max-width: 1660px) 100vw, 1660px" /></a><br />
Click add and this is how the backend tab should look like.<br />
<a href="https://blog.andreev.it/wp-content/uploads/2022/01/P158-12.png"><img loading="lazy" decoding="async" src="https://blog.andreev.it/wp-content/uploads/2022/01/P158-12.png" alt="" width="1662" height="1206" class="aligncenter size-full wp-image-9060" srcset="https://blog.andreev.it/wp-content/uploads/2022/01/P158-12.png 1662w, https://blog.andreev.it/wp-content/uploads/2022/01/P158-12-300x218.png 300w, https://blog.andreev.it/wp-content/uploads/2022/01/P158-12-1024x743.png 1024w, https://blog.andreev.it/wp-content/uploads/2022/01/P158-12-768x557.png 768w, https://blog.andreev.it/wp-content/uploads/2022/01/P158-12-1536x1115.png 1536w, https://blog.andreev.it/wp-content/uploads/2022/01/P158-12-1170x849.png 1170w, https://blog.andreev.it/wp-content/uploads/2022/01/P158-12-585x424.png 585w" sizes="(max-width: 1662px) 100vw, 1662px" /></a><br />
Move to the other options (tags, review) and create the application gateway. Once created, you&#8217;ll see a public IP under the <strong>Overview</strong> for the app gateway. Copy or write down this IP somewhere.</p>
<h1>Private endpoint</h1>
<p>So, we have a Web App with a public URL, but we want to put the app behind an App Gateway. We can do that later when we specify the backend target, but then the Web App can be accessed equally from the Web App URL and the App Gateway IP. We don&#8217;t want this. We want the app to be accessible from the App Gateway only. For that we need a <strong>private endpoint</strong>.<br />
NOTE: Once you enable the private endpoint, you won&#8217;t be able to SSH to the Web App from your browser that uses a public SSH URL. You just can&#8217;t. The solution is to use DevOps pipelines with self-hosted agents or use <strong>Deployment Slots</strong> and swap them. I&#8217;ll use Deployment Slots for this demo, but you need automation and Azure DevOps for the deployment in real world.<br />
Go to the <strong>App Services</strong>, click on the <strong>Networking</strong> from the blade and then click on <strong>Private endpoints</strong>. Click <strong>Add</strong>.<br />
<a href="https://blog.andreev.it/wp-content/uploads/2022/01/P158-14.png"><img loading="lazy" decoding="async" src="https://blog.andreev.it/wp-content/uploads/2022/01/P158-14.png" alt="" width="630" height="638" class="aligncenter size-full wp-image-9066" srcset="https://blog.andreev.it/wp-content/uploads/2022/01/P158-14.png 630w, https://blog.andreev.it/wp-content/uploads/2022/01/P158-14-296x300.png 296w, https://blog.andreev.it/wp-content/uploads/2022/01/P158-14-585x592.png 585w" sizes="(max-width: 630px) 100vw, 630px" /></a><br />
Name the private endpoint, make sure it&#8217;s in its own subnet (<strong>subPE</strong>) and make sure that it&#8217;s integrated with the private DNS zone.<br />
<a href="https://blog.andreev.it/wp-content/uploads/2022/01/P158-15.png"><img loading="lazy" decoding="async" src="https://blog.andreev.it/wp-content/uploads/2022/01/P158-15.png" alt="" width="1140" height="1060" class="aligncenter size-full wp-image-9069" /></a><br />
Now, what we did is created the private endpoint which means we are making the Web App accessible from the internal network only. This also disables the public URL that was assigned to the app. If you go to the URL, you&#8217;ll get <strong>Error 403 &#8211; forbidden</strong>. That&#8217;s good, that&#8217;s what we wanted anyway.<br />
Go to the <strong>Application Gateway</strong>, click on the <strong>Backend pools</strong> from the menu and click on the actual backend pool. Add the target and click <strong>Save</strong>. The target is obviously the App Service.<br />
<a href="https://blog.andreev.it/wp-content/uploads/2022/01/P158-16.png"><img loading="lazy" decoding="async" src="https://blog.andreev.it/wp-content/uploads/2022/01/P158-16.png" alt="" width="1278" height="458" class="aligncenter size-full wp-image-9076" srcset="https://blog.andreev.it/wp-content/uploads/2022/01/P158-16.png 1278w, https://blog.andreev.it/wp-content/uploads/2022/01/P158-16-300x108.png 300w, https://blog.andreev.it/wp-content/uploads/2022/01/P158-16-1024x367.png 1024w, https://blog.andreev.it/wp-content/uploads/2022/01/P158-16-768x275.png 768w, https://blog.andreev.it/wp-content/uploads/2022/01/P158-16-1170x419.png 1170w, https://blog.andreev.it/wp-content/uploads/2022/01/P158-16-585x210.png 585w" sizes="(max-width: 1278px) 100vw, 1278px" /></a><br />
At this point, the App Gateway IP should show you the PHP info site, the App Service URL should give you Error 403 and the SSH for the App Service should also give you Error 403. So, how do I make changes in the app? Well, Azure DevOps, but for now, use <strong>Deployment Slots</strong>.</p>
<h1>Deployment Slots</h1>
<p>Go to the <strong>App Service</strong> and under <strong>Deployment</strong> click on <strong>Deployment slots</strong>. Click <strong>Add Slot</strong>. Name the slot, in my case <strong>dev</strong> and copy the settings from the existing app service. The new slot won&#8217;t get the private endpoint and that&#8217;s what we want. The new slot is just a new app service environment. It&#8217;s accessible from outside using the URL with a <strong>-dev</strong> (in my case) suffix and it&#8217;s not accessible over the App Gateway.<br />
<a href="https://blog.andreev.it/wp-content/uploads/2022/01/P158-17.png"><img loading="lazy" decoding="async" src="https://blog.andreev.it/wp-content/uploads/2022/01/P158-17.png" alt="" width="1196" height="462" class="aligncenter size-full wp-image-9090" srcset="https://blog.andreev.it/wp-content/uploads/2022/01/P158-17.png 1196w, https://blog.andreev.it/wp-content/uploads/2022/01/P158-17-300x116.png 300w, https://blog.andreev.it/wp-content/uploads/2022/01/P158-17-1024x396.png 1024w, https://blog.andreev.it/wp-content/uploads/2022/01/P158-17-768x297.png 768w, https://blog.andreev.it/wp-content/uploads/2022/01/P158-17-1170x452.png 1170w, https://blog.andreev.it/wp-content/uploads/2022/01/P158-17-585x226.png 585w" sizes="(max-width: 1196px) 100vw, 1196px" /></a><br />
Click on the app slot that you just created and go to the <strong>SSH</strong> menu under the <strong>Development Tools</strong>. You&#8217;ll be able to access the SSH shell in a browser. Once there, download a TLS certificate that we&#8217;ll use to <a href="https://docs.microsoft.com/en-us/azure/mysql/flexible-server/how-to-connect-tls-ssl" rel="noopener" target="_blank">connect</a> to the MySQL database server. </p>
<pre class="brush: bash; title: ; notranslate">
cd /home
wget --no-check-certificate https://dl.cacerts.digicert.com/DigiCertGlobalRootCA.crt.pem
</pre>
<p>We&#8217;ll also replace the initial PHP info page from our current web app. Instead we&#8217;ll try to connect to a MySQL server (that doesn&#8217;t exist at this point), but you&#8217;ll get an idea how to make changes. Just copy &#038; paste this code, it will create the file for you.</p>
<pre class="brush: bash; highlight: [5,6,7]; title: ; notranslate">
cat &lt;&lt; 'EOF' &gt; /home/site/wwwroot/index.php
&lt;?php
$conn = mysqli_init();

$host='mysqlwebappha.mysql.database.azure.com';
$user='dbadmin';
$pass='Pa$$w0rd';
$db='mysql';

mysqli_ssl_set($conn,NULL,NULL, &quot;/home/DigiCertGlobalRootCA.crt.pem&quot;, NULL, NULL);
mysqli_real_connect($conn, $host, $user, $pass, $db, 3306, MYSQLI_CLIENT_SSL);
if (mysqli_connect_errno($conn)) {
    die('Failed to connect to MySQL: '.mysqli_connect_error());
} else {
    if($result = $conn-&gt;query('SHOW TABLES')) {
        while($row = $result-&gt;fetch_array()) {
            $tables&#x5B;] = $row&#x5B;0];
        }
    }
    print_r($tables);
}
?&gt;
EOF
</pre>
<p>Now, if you go to the <strong>Overview</strong> menu for the dev <strong>Deployment Slot</strong>, you&#8217;ll see a different URL. Go to this URL and you should see an error &#8220;<em>Failed to connect to MySQL: php_network_getaddresses: getaddrinfo failed: Name or service not known</em>&#8220;. That&#8217;s OK, the database doesn&#8217;t exist. The URL for the dev slot is from the web app, it doesn&#8217;t go through the <strong>Application Gateway</strong>. All we have to do is swap the deployment slots now.<br />
<a href="https://blog.andreev.it/wp-content/uploads/2022/01/P158-18.png"><img loading="lazy" decoding="async" src="https://blog.andreev.it/wp-content/uploads/2022/01/P158-18.png" alt="" width="2654" height="526" class="aligncenter size-full wp-image-9100" srcset="https://blog.andreev.it/wp-content/uploads/2022/01/P158-18.png 2654w, https://blog.andreev.it/wp-content/uploads/2022/01/P158-18-300x59.png 300w, https://blog.andreev.it/wp-content/uploads/2022/01/P158-18-1024x203.png 1024w, https://blog.andreev.it/wp-content/uploads/2022/01/P158-18-768x152.png 768w, https://blog.andreev.it/wp-content/uploads/2022/01/P158-18-1536x304.png 1536w, https://blog.andreev.it/wp-content/uploads/2022/01/P158-18-2048x406.png 2048w, https://blog.andreev.it/wp-content/uploads/2022/01/P158-18-1920x381.png 1920w, https://blog.andreev.it/wp-content/uploads/2022/01/P158-18-1170x232.png 1170w, https://blog.andreev.it/wp-content/uploads/2022/01/P158-18-585x116.png 585w" sizes="(max-width: 2654px) 100vw, 2654px" /></a><br />
Click on <strong>Swap</strong>. This will put the dev slot under the <strong>Application Gateway</strong>.<br />
<a href="https://blog.andreev.it/wp-content/uploads/2022/01/P158-19.png"><img loading="lazy" decoding="async" src="https://blog.andreev.it/wp-content/uploads/2022/01/P158-19.png" alt="" width="1162" height="910" class="aligncenter size-full wp-image-9101" srcset="https://blog.andreev.it/wp-content/uploads/2022/01/P158-19.png 1162w, https://blog.andreev.it/wp-content/uploads/2022/01/P158-19-300x235.png 300w, https://blog.andreev.it/wp-content/uploads/2022/01/P158-19-1024x802.png 1024w, https://blog.andreev.it/wp-content/uploads/2022/01/P158-19-768x601.png 768w, https://blog.andreev.it/wp-content/uploads/2022/01/P158-19-585x458.png 585w" sizes="(max-width: 1162px) 100vw, 1162px" /></a><br />
Once the swap is complete (about a minute), if you go to the App Gateway URL (the IP address), you&#8217;ll see the same error about the database connection. Let&#8217;s do the database now.</p>
<h1>Database</h1>
<p>Look at the PHP code for <strong>index.php</strong> slightly above. The highlighted lines is how we&#8217;ll name the database <strong>mysqlwebappha</strong>, with admin called <strong>dbadmin</strong> and the password on line 7. There are two types of MySQL databases, <strong>Flexible</strong> and <strong>Single Server</strong> MySQL database. Read about them <a href="https://docs.microsoft.com/en-us/azure/mysql/overview">here</a>. We&#8217;ll go with flexible MySQL server.<br />
Look at the parameters that I&#8217;ve used. Make sure you use the same name or you have to modify the code in <strong>index.php</strong> file. Use <strong>General Purpose server</strong> and version 5.7.<br />
<a href="https://blog.andreev.it/wp-content/uploads/2022/01/P158-20.png"><img loading="lazy" decoding="async" src="https://blog.andreev.it/wp-content/uploads/2022/01/P158-20.png" alt="" width="1444" height="1352" class="aligncenter size-full wp-image-9103" srcset="https://blog.andreev.it/wp-content/uploads/2022/01/P158-20.png 1444w, https://blog.andreev.it/wp-content/uploads/2022/01/P158-20-300x281.png 300w, https://blog.andreev.it/wp-content/uploads/2022/01/P158-20-1024x959.png 1024w, https://blog.andreev.it/wp-content/uploads/2022/01/P158-20-768x719.png 768w, https://blog.andreev.it/wp-content/uploads/2022/01/P158-20-1170x1095.png 1170w, https://blog.andreev.it/wp-content/uploads/2022/01/P158-20-585x548.png 585w" sizes="(max-width: 1444px) 100vw, 1444px" /></a><br />
Enable HA and use the username and password as in the <strong>index.php file</strong>.<br />
<a href="https://blog.andreev.it/wp-content/uploads/2022/01/P158-21.png"><img loading="lazy" decoding="async" src="https://blog.andreev.it/wp-content/uploads/2022/01/P158-21.png" alt="" width="1472" height="854" class="aligncenter size-full wp-image-9104" srcset="https://blog.andreev.it/wp-content/uploads/2022/01/P158-21.png 1472w, https://blog.andreev.it/wp-content/uploads/2022/01/P158-21-300x174.png 300w, https://blog.andreev.it/wp-content/uploads/2022/01/P158-21-1024x594.png 1024w, https://blog.andreev.it/wp-content/uploads/2022/01/P158-21-768x446.png 768w, https://blog.andreev.it/wp-content/uploads/2022/01/P158-21-1170x679.png 1170w, https://blog.andreev.it/wp-content/uploads/2022/01/P158-21-585x339.png 585w" sizes="(max-width: 1472px) 100vw, 1472px" /></a><br />
Choose a <strong>VNET integrated</strong> access and specify <strong>subDB</strong> for the subnet.<br />
<a href="https://blog.andreev.it/wp-content/uploads/2022/01/P158-22.png"><img loading="lazy" decoding="async" src="https://blog.andreev.it/wp-content/uploads/2022/01/P158-22.png" alt="" width="1466" height="1192" class="aligncenter size-full wp-image-9107" srcset="https://blog.andreev.it/wp-content/uploads/2022/01/P158-22.png 1466w, https://blog.andreev.it/wp-content/uploads/2022/01/P158-22-300x244.png 300w, https://blog.andreev.it/wp-content/uploads/2022/01/P158-22-1024x833.png 1024w, https://blog.andreev.it/wp-content/uploads/2022/01/P158-22-768x624.png 768w, https://blog.andreev.it/wp-content/uploads/2022/01/P158-22-1170x951.png 1170w, https://blog.andreev.it/wp-content/uploads/2022/01/P158-22-585x476.png 585w" sizes="(max-width: 1466px) 100vw, 1466px" /></a><br />
Finish with the remaining settings (use default) and click <strong>Create</strong>. While the database is being created (it takes about 20 mins), go to the <strong>App Services</strong> and click on the <strong>Networking</strong> from the menu. Click on <strong>VNET integration</strong>.<br />
<a href="https://blog.andreev.it/wp-content/uploads/2022/01/P158-23.png"><img loading="lazy" decoding="async" src="https://blog.andreev.it/wp-content/uploads/2022/01/P158-23.png" alt="" width="2506" height="1418" class="aligncenter size-full wp-image-9109" srcset="https://blog.andreev.it/wp-content/uploads/2022/01/P158-23.png 2506w, https://blog.andreev.it/wp-content/uploads/2022/01/P158-23-300x170.png 300w, https://blog.andreev.it/wp-content/uploads/2022/01/P158-23-1024x579.png 1024w, https://blog.andreev.it/wp-content/uploads/2022/01/P158-23-768x435.png 768w, https://blog.andreev.it/wp-content/uploads/2022/01/P158-23-1536x869.png 1536w, https://blog.andreev.it/wp-content/uploads/2022/01/P158-23-2048x1159.png 2048w, https://blog.andreev.it/wp-content/uploads/2022/01/P158-23-1920x1086.png 1920w, https://blog.andreev.it/wp-content/uploads/2022/01/P158-23-1170x663.png 1170w, https://blog.andreev.it/wp-content/uploads/2022/01/P158-23-585x331.png 585w" sizes="(max-width: 2506px) 100vw, 2506px" /></a><br />
Click on <strong>Add VNET</strong> from the new blade and choose <strong>subApp</strong> for the subnet.<br />
<a href="https://blog.andreev.it/wp-content/uploads/2022/01/P158-24.png"><img loading="lazy" decoding="async" src="https://blog.andreev.it/wp-content/uploads/2022/01/P158-24.png" alt="" width="1152" height="690" class="aligncenter size-full wp-image-9110" srcset="https://blog.andreev.it/wp-content/uploads/2022/01/P158-24.png 1152w, https://blog.andreev.it/wp-content/uploads/2022/01/P158-24-300x180.png 300w, https://blog.andreev.it/wp-content/uploads/2022/01/P158-24-1024x613.png 1024w, https://blog.andreev.it/wp-content/uploads/2022/01/P158-24-768x460.png 768w, https://blog.andreev.it/wp-content/uploads/2022/01/P158-24-585x350.png 585w" sizes="(max-width: 1152px) 100vw, 1152px" /></a><br />
&#8230;and if you go to the website, you&#8217;ll see a dumb of all the tables for the mysql database.<br />
<a href="https://blog.andreev.it/wp-content/uploads/2022/01/P158-25.png"><img loading="lazy" decoding="async" src="https://blog.andreev.it/wp-content/uploads/2022/01/P158-25.png" alt="" width="1442" height="314" class="aligncenter size-full wp-image-9112" srcset="https://blog.andreev.it/wp-content/uploads/2022/01/P158-25.png 1442w, https://blog.andreev.it/wp-content/uploads/2022/01/P158-25-300x65.png 300w, https://blog.andreev.it/wp-content/uploads/2022/01/P158-25-1024x223.png 1024w, https://blog.andreev.it/wp-content/uploads/2022/01/P158-25-768x167.png 768w, https://blog.andreev.it/wp-content/uploads/2022/01/P158-25-1170x255.png 1170w, https://blog.andreev.it/wp-content/uploads/2022/01/P158-25-585x127.png 585w" sizes="(max-width: 1442px) 100vw, 1442px" /></a></p>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.andreev.it/2022/01/azure-azure-app-services-high-availability/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
