<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Scaling on Journey through Cloud &amp; Code</title><link>https://gurupasupathy.com/tags/scaling/</link><description>Recent content in Scaling on Journey through Cloud &amp; Code</description><generator>Hugo</generator><language>en-us</language><lastBuildDate>Sat, 25 Apr 2020 00:00:00 +0000</lastBuildDate><atom:link href="https://gurupasupathy.com/tags/scaling/index.xml" rel="self" type="application/rss+xml"/><item><title>Scheduling vertical scaling using Microsoft Azure Automation Accounts</title><link>https://gurupasupathy.com/post/2020-04-25_scheduling-vertical-scaling/</link><pubDate>Sat, 25 Apr 2020 00:00:00 +0000</pubDate><guid>https://gurupasupathy.com/post/2020-04-25_scheduling-vertical-scaling/</guid><description>&lt;p&gt;&lt;img loading="lazy" src="https://gurupasupathy.com/img/1__6HRU03UvgOt__5ih3ssEDXw.jpeg"&gt;&lt;/p&gt;
&lt;p&gt;Scaling cloud resources dynamically is a fascinating topic. Microsoft Azure provide quite a few ways to dynamically scale resources. This article focuses on creating a scheduled &lt;em&gt;vertical scaling&lt;/em&gt; (scaled up/down) of App Services. The approach outlined here can be used for other Azure resource like SQL Databases, Redis Cache or in fact pretty much most of the Azure resources that support scaling. Just to clarify right at the outset, we are talking about vertical scaling (between pricing tiers) and not horizontal scaling (scale in/out) wherein we deal with the number of instances at our disposal.&lt;/p&gt;</description><content:encoded><![CDATA[<p><img loading="lazy" src="/img/1__6HRU03UvgOt__5ih3ssEDXw.jpeg"></p>
<p>Scaling cloud resources dynamically is a fascinating topic. Microsoft Azure provide quite a few ways to dynamically scale resources. This article focuses on creating a scheduled <em>vertical scaling</em> (scaled up/down) of App Services. The approach outlined here can be used for other Azure resource like SQL Databases, Redis Cache or in fact pretty much most of the Azure resources that support scaling. Just to clarify right at the outset, we are talking about vertical scaling (between pricing tiers) and not horizontal scaling (scale in/out) wherein we deal with the number of instances at our disposal.</p>
<p>It is a common knowledge that Azure provides out-of-the-box options to <strong><em>scale out/ scale in</em></strong> based on the scaling rules for App Service plan but there is no way to scale up / scale down as per some schedule.</p>
<p>For instance, there is no direct way to say that between 10 AM and 12 Noon, let my App Service plan run on P2V2 and come back to P1V2 there after or have my SQL Server move up to P6 for a few hours before coming back to S2. In other words, no option to <strong><em>scale up/scale down</em></strong> based on schedule</p>
<blockquote>
<p>Note on Serverless Azure SQL Database :- We have Serverless Azure SQL Databases with two key capabilities which make them attractive in terms of cost. 1. The option to auto scale up / down between the minimum and maximum threshold 2. Auto-pause — wherein the SQL Server is stopped after a predefined period of inactivity till some activity is detected again. You don’t get charged for the period of inactivity. The downside is that it will take some time of the SQL Server to warm up and be available for the next use after the period of inactivity. Serverless is best suited for test / dev environments where you have tolerance to the brief period of connection unavailability during the warm-up. There could also be slight performance degradation for sometime as the cache memory are gradually reclaimed. Serverless is not for your use case if these limitations are not acceptable. Furthermore, there are cases when although your usage will be limited for an interval you cannot afford to shut down the server using auto pause. Without auto pause you will be charged for the minimum number of vCores and minimum memory configured. For more details, refer to Microsoft documentation on <a href="https://docs.microsoft.com/en-us/azure/azure-sql/database/serverless-tier-overview">Azure Serverless SQL Database</a></p>
</blockquote>
<blockquote>
<p>So, if your case is such that you will want to use DTU based provisioning and still want scaling based on a schedule as you have predictable utilisation, you can use the approach outlined in this article. One example that comes to my mind is bumping up your DTU for a few hours when you are doing a performance test or scaling down during a seasonal / weekend low utilisation to save costs.</p>
</blockquote>
<p>Alright, now that we have context set, let us move on to see how we can achieve this scheduled vertical scaling for Azure resource in the following section</p>
<p>To start with, create an automation account. Details on how to create automation account can be found <a href="https://docs.microsoft.com/en-us/azure/automation/automation-create-standalone-account">here</a>. Azure Automation allows us to invoke runbooks as per a schedule. We will leverage this capability for our purpose. Please remember to select the option to create a RunAs account while creating the Automation account as shown below. This is the principle under with the runbooks can execute.</p>
<p><img loading="lazy" src="/img/1__XoHZ7Nof1sdJkKRcwhXCaA.png"></p>
<p>After the automation account is created, create two Runbooks which will be invoked by a scheduler to perform the scaling operation automatically without our intervention. These runbooks will contain PowerShell scripts to perform the scaling operation based on your need. (one for Scale up and another for Scale down) The fact that we use PowerShell to perform the scaling gives us the option to scale pretty much all resource for which you can get hold of PowerShell scripts to scale; and the best source for PowerShell reference is <a href="https://docs.microsoft.com/en-us/powershell/scripting/overview?view=powershell-7">Microsoft’s official documentation</a>.</p>
<p>Now that you have the automation account and the runbooks that you need, create a schedule and link these runbooks as per your need. (<em>I won’t go into details on creating a schedule as it is very well documented and simple. Refer to Microsoft’s documentation on how to create a</em> <a href="https://docs.microsoft.com/en-us/azure/automation/shared-resources/schedules"><em>Schedule</em></a> )</p>
<p>So, for instance, the below schedule will automatically call the “ScaleDown” runbook at 5:10 AM on 7th Feb</p>
<p><img loading="lazy" src="/img/0__qk76rY21a2xOWrxz.jpg"></p>
<p>The below PowerShell script can be used to scale up / down an App Service Plan</p>
<p>Write-Output &ldquo;API Scale&rdquo;</p>
<p>$connectionName = &ldquo;AzureRunAsConnection&rdquo;<br>
try {<br>
$servicePrincipalConnection=Get-AutomationConnection -Name $connectionName</p>
<p>Add-AzureRmAccount -ServicePrincipal -TenantId $servicePrincipalConnection.TenantId -ApplicationId $servicePrincipalConnection.ApplicationId -CertificateThumbprint $servicePrincipalConnection.CertificateThumbprint</p>
<p>Set-AzureRmAppServicePlan -ResourceGroupName &ldquo;&laquo;<strong>yourresourcegroup</strong>&rdquo; -Name &ldquo;&laquo;<strong>yourappserviceplanname</strong>&rdquo;  -Tier PremiumV2 -NumberofWorkers 2 -WorkerSize &ldquo;Medium&rdquo;}</p>
<p>catch {<br>
if (!$servicePrincipalConnection){<br>
$ErrorMessage = &ldquo;Connection $connectionName not found.&rdquo;<br>
throw $ErrorMessage } else{<br>
Write-Error -Message $_.Exception<br>
throw $_.Exception<br>
}}</p>
<blockquote>
<p>In case you receive an error as below, go and update the PowerShell modules in your automation account. That should fix the issue</p>
</blockquote>
<blockquote>
<p><strong>The term ‘Set-AzureRmAppServicePlan’ is not recognized as the name of a cmdlet, function, script file, or operable program.</strong></p>
</blockquote>
<p>Below, I have provided a sample PowerShell to scale a SQL database; it scales to database to P1 tier. This script uses a credential to perform the DB scaling as opposed to the AzureRunAsAccount in the previous PowerShell.</p>
<p>To create a new credential, navigate to your automation account and select the “Credentials” option in the “Shared Resources” section. Refer to the below screen shot showing the credential creation</p>
<p><img loading="lazy" src="/img/1__tvODqy4v1CAZN__sbLLDL7g.png"></p>
<p>param([parameter(Mandatory=$true)] [PSCredential] $Credential )</p>
<p># Name of the Azure SQL Database server<br>
[string] $SqlServerName = &ldquo;<strong>yourserver</strong>.database.windows.net&rdquo;</p>
<p>$Servercredential = New-Object System.Management.Automation.PSCredential($Credential.UserName, (($Credential).GetNetworkCredential().Password | ConvertTo-SecureString -asPlainText -Force))</p>
<p>$CTX = New-AzureSqlDatabaseServerContext -ServerName $SqlServerName -Credential $ServerCredential</p>
<p>[string] $DatabaseName = &ldquo;<strong>yourdb</strong>&rdquo;<br>
[string] $Edition = &ldquo;Premium&rdquo;<br>
[string] $PerfLevel = &ldquo;P1&rdquo;<br>
$Db = Get-AzureSqlDatabase  $CTX –DatabaseName $DatabaseName</p>
<p>Write-Output &ldquo;Database Scale state &quot; - $Db.ServiceObjectiveAssignementStateDescription</p>
<p>if($Db.ServiceObjectiveName -ne $PerfLevel -and $Db.ServiceObjectiveAssignementStateDescription -ne &ldquo;Pending&rdquo;){<br>
$ServiceObjective = Get-AzureSqlDatabaseServiceObjective $CTX -ServiceObjectiveName $PerfLevel</p>
<p># Set the new edition/performance level<br>
#None, Business, Web, Premium, Basic, Standard&rdquo;</p>
<p>Write-Output &ldquo;Trigger the scale operation&rdquo;<br>
Set-AzureSqlDatabase $CTX –Database $Db –ServiceObjective $ServiceObjective –Edition $Edition -Force</p>
<p>Write-Output &ldquo;Completed vertical scale&rdquo;<br>
}else{<br>
Write-Output &ldquo;The DB is already in the target pricing tier Or DB is currenlty being scale up / down&rdquo;}</p>
<p>This same approach can be applied for other Azure resources also. Go on and try it out!</p>
<p>Happy Scaling!</p>
]]></content:encoded></item></channel></rss>