Using OMS and Azure Functions to restart Azure Web…
From time to time I have had problems with this blog and other sites running in Azure. Occasionally they throw HTTP 5XX errors and when it doesnt fix it self I will have to restart the web app. By using Operations Management Suite (OMS) with the web app analytics solution added, I created an alert calling an Azure Function to restart the affected web app. It’s keeping the sites up until I can get to the bottom of the problem or change provider.. Anyway, this is how I set it up.
Before we create the actual function we will we have a few dependencies.
- OMS Workspace with the Web App Analytics enabled (currently in public preview) –Not Covered
- Azure Function account –Not Covered
- Azure AD application used for authentication
Create an application for authentication
In order to access and manage Azure resources from Azure Functions we need to create an application in Azure Active Directory and assign it the proper permissions. I Used Powershell to do this, but it’s perfectly fine to use the online console.
The script below will create a new application and assign it “web site contributor” role. If you need other security rights chose a different role. You can read more about the built-in roles here
Please edit the script to your needs. You will need the App Id, app password and TenantId to use as variables in our function.
Login-AzureRmAccount #Add azure application to use for authenication from azure function $application = New-AzureRmADApplication -DisplayName "AUTH: Azure Function" -HomePage "http://yourwebsites/functions" -IdentifierUris "https://adatum.no/AzureFunctions" -Password "***********************************" #Grab the application ID $appid = $application.ApplicationId.Guid #create a service principal for the AAD app New-AzureRmADServicePrincipal -ApplicationId $appid #add a role to the newly created principal. #I have chosen Web Site Contributor, but if you want to use anything else. please see https://docs.microsoft.com/en-us/azure/active-directory/role-based-access-built-in-roles New-AzureRmRoleAssignment -RoleDefinitionName 'Website Contributor' -ServicePrincipalName $appid #Get the tenant ID $TenantId = (Get-AzureRmSubscription -SubscriptionName "NAME").TenantId
Finished:
Setting up the Function app
First, create three environment variables in your function app containing your application ID, password and tenant id.
FunctionApp>settings>Manage Application Settings
I had appreciated examples of how to encrypt this password
Next, the actual code.
#Get input $input = Get-Content $req -Raw | ConvertFrom-Json $AppName = $input.appName $ResourceGroup = $input.resourceGroupName #Get user and password, create credential object $User = $env:AzureFunctionAppID $Pass = ConvertTo-SecureString -String $env:AzureFunctionAppPwd -AsPlainText -Force $Credential = New-Object System.Management.Automation.PSCredential $user,$pass #Login Add-AzureRmAccount -Credential $Credential -TenantId $env:TennantId -ServicePrincipal #Restart the web app and output state Restart-AzureRmWebApp -name $AppName -ResourceGroupname $ResourceGroup $Output = (Get-AzureRmWebApp -name $AppName).State Out-File -Encoding Ascii -FilePath $res -inputObject $output
This Powershell function will use the environment variables/AAD application to login to your Azure environment and restart the WebApp provided in the input. I have set it up to require AppName and ResourceGroup (name) in the json post.
Send the following in the test pane to verify that the function works.
{ "appName": "mywebApp", "resourceGroupName": "MyWebbAppResourceGroup" }
There isn’t much response other than the (hopefully) “Running” status, but you can confirm everything in you activity log. The user initiated will be your application we created in the first step.
OMS Alert with Json payload
To automate the process, OMS need to trigger the function when too many 500-errors occur. Azure Web App Analytics (preview) in OMS already have views enabled for different error codes, response time etc, so you can use this for what ever you need. I wanted to restart a specific web app based on error 500’s. This is the search string I ended up with
Type:AzureMetrics ResourceId=*"/MICROSOFT.WEB/SITES/"* (MetricName=Requests OR MetricName=Http*) MetricName=Http5xx Resource=WEBAPPNAME
Based on that search result i created an alert sending a webhook with a custom Json payload
{ "appName": "mywebApp", "resourceGroupName": "MyWebbAppResourceGroup" }
OMS should now kick off your Azure Function and restart the website without your interaction. To verify you can use the acitivity log and OMS’ alert log.