I had a task recently to enable Proactive CPU Monitoring for an Azure Web App as part of our deployment process.
Often the easiest way to discover how to deploy something to Azure is to build it in the portal and then export the ARM template (hopefully someday export to bicep). When I set up a test app, enabled these settings, and exported the template, these settings were disappointingly missing.
I reached out to some folks on Twitter and Puneet Gupta was kind enough to reply and post this article .
What Puneet shared worked well to enable the setting, however it is only part of the solution. The App Service requires WEBSITE_DAAS_STORAGE_SASURI
configuration setting to exist. This setting is a Shared Access Signature URI to a storage account. The portal can generate this for you, but much like the monitoring settings this will be wiped away with a new deployment.
For the rest of this post, I will this assume you have an App Service and a storage account setup. Both of those are easy enough to deploy, so I won't take the time to go over that.
The complete solution is to generate this token with Azure PowerShell tasks in Azure DevOps.
$webApp = "App Name"
$resourceGroup = "Resource Group"
$storageAccount = "Storage Account"
$container = "memorydumps"
$storageAccountKey = (Get-AzStorageAccountKey -ResourceGroupName $resourceGroup -Name $storageAccount).Value[0]
$context = New-AzStorageContext -StorageAccountName $storageAccount -StorageAccountKey $storageAccountKey
$containerUri = (Get-AzStorageContainer -Container $container -Context $context).CloudBlobContainer.Uri.AbsoluteUri
$startTime = (Get-Date).AddMinutes(-15)
$endTime = $startTime.AddDays(7)
$sasToken = New-AzStorageAccountSASToken -Permission acdlpruw -StartTime $startTime -ExpiryTime $endTime -Context $context -Protocol HttpsOrHttp -ResourceType Container,Object -Service Blob,Queue,Table
$sasUrl = "$containerUri$sasToken"
$settings=(Get-AzWebApp -Name '$webApp' -ResourceGroupName $resourceGroup).SiteConfig.AppSettings
$newsettings = @{}
$settings | ForEach-Object { $newsettings[$_.Name] = $_.Value }
$newsettings["WEBSITE_DAAS_STORAGE_SASURI"] = $sasUrl
Set-AzWebApp -AppSettings $newsettings -Name '$webApp' -ResourceGroupName $resourceGroup
You can provide webApp, resourceGroup and storageAccount via a library or variable group. The container name should remain the same, however as the CPU monitoring will create and use this container for memory dumps.
Line 6 gets a storage account access key. We get a storage context on line 7 which we use to get the container URI and the SAS token on 8 and 11.
The token requires a lifetime it's valid for. If you deploy often, you can set this to be short-lived.
Line 12 combines the storage URI and the SAS token to give use the complete URL.
The next part shows how to update the web app configuration setting with this URL. Annoyingly, there doesn't seem to be a way to just add a new setting to the web app. You have to collect the existing settings first, make your change and push the whole thing back up. An additional annoyance is that the AppSettings
returns an IList<NameValuePair>
but Set-AzWebApp
requires a hashtable. This means that you need line 16-19 to loop over the existing settings, add that to a new hashtable and THEN add or set a new setting.
This code comes from Puneet's post above.
$subscriptionId = "Your_Subscription_Id" # Your App's SubscriptionId
$webapp = "App Name" # Your App's Name
$rg = "Resource Group" # Your App's Resource Group
$path = "/subscriptions/$subscriptionId/resourceGroups/$rg/providers/Microsoft.Web/sites/$webapp/extensions/daas/api/cpumonitoring?api-Version=2015-08-01"
$monitoringSettings = @{
#Configure Action - An action that you want to take when the above condition is met
Mode="CollectAndKill";
#Monitor Frequency - This is how frequently the rule will be evaluated
MonitorDuration=15;
#Threshold Seconds - For the rule to trigger, CPU should exceed % for this many seconds
ThresholdSeconds=30;
#CPU Threshold% - This is the CPU threshold at which the rule will be triggered
CpuThreshold=75;
#Monitor Web job processes
MonitorScmProcesses=$true;
#Maximum Actions - Maximum number of memory dumps to be collected by this rule
MaxActions=2;
#Maximum Duration - Rule will be deactivated after this duration even if no data is collected
MaximumNumberOfHours=336;
}
$payload = $monitoringSettings | ConvertTo-Json
Invoke-AzRestMethod -Path $path -Method "POST" -Payload $payload
Here's what this looks like in the Azure portal.
Obviously, these settings need to be adjusted for your particular requirements.
It's odd to me that Azure does not provide this as part of the ARM templates.
There was basically no documentation on these either.
I hope that helps you in your Azure journey. Thanks again to Puneet for pointing me in the right direction.
Comments
You can also comment directly on GitHub.