Skip to content
/

Adding Application Logging (Blob) to a Azure Web App Service using PowerShell

These days it’s normal to deploy and configure all aspects of your Azure Resources using the Azure Resource Manager and the accompanying ARM Templates. But sometimes you walk into a missing feature that’s is not (yet) available in the ARM system.
The other day I wanted to configure Application Logging on Blob Storage for a Web App Service and found out this needs a SAS URL. And this is something an ARM template can’t provide for you.

In this post, I will walk you through the necessary PowerShell code to run. For example, after your ARM template has been deployed. At the end of the post you will find the link to the source code.

The ARM template

In the ARM template, we deploy a Storage Account and a Web App Service.

{
    "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
    "contentVersion": "1.0.0.0",
    "resources": [
        {
            "type": "Microsoft.Storage/storageAccounts",
            "kind": "Storage",
            "name": "loremipsumstore",
            "apiVersion": "2016-01-01",
            "sku": {
                "name": "Standard_LRS"
            },
            "location": "[resourceGroup().location]"
        },
        {
            "type": "Microsoft.Web/serverfarms",
            "kind": "app",
            "name": "LoremIpsumAppService",
            "sku": {
                "name": "B1"
            },
            "apiVersion": "2015-08-01",
            "location": "[resourceGroup().location]",
            "properties": {
            "name": "LoremIpsumAppService",
                "numberOfWorkers": 1
            },
            "resources": [
                {
                    "type": "Microsoft.Web/sites",
                    "kind": "app",
                    "name": "LoremIpsumWebApp",
                    "apiVersion": "2015-08-01",
                    "location": "[resourceGroup().location]",
                    "properties": {
                        "name": "LoremIpsumWebApp"
                    },
                    "dependsOn": [
                        "[resourceId('Microsoft.Web/serverfarms', 'LoremIpsumAppService')]"
                    ]
                }
            ]
        }
    ]
}

The problem

When we configure the Application Logging to Blob Storage using the Azure Portal we see the following properties in the JSON of the Web App Service using the Azure Resource Explorer.

"applicationLogs": {
  "azureBlobStorage": {
    "level": "Verbose",
    "sasUrl": "https://loremipsumstore.blob.core.windows.net/webapp-logs?sv=2015-04-05&sr=c&sig=XXX...XXX&st=2017-05-29T22:00:00Z&se=2217-05-29T22:00:00Z&sp=rwdl",
    "retentionInDays": 30
  }
}

But secretly, the last two properties are stored in the AppSettings. When we look there we see the following 2 keys:

DIAGNOSTICS_AZUREBLOBCONTAINERSASURL    https://loremipsumstore.blob.core.windows.net/webapp-logs?sv=2015-04-05&sr=c&sig=XXX...XXX&st=2017-05-29T22:00:00Z&se=2217-05-29T22:00:00Z&sp=rwdl
DIAGNOSTICS_AZUREBLOBRETENTIONINDAYS    30

Setting AppSettings with an ARM template isn’t that hard. But the URL we need to set can’t be predefined and ARM templates don’t have support for the generation of a SAS URL.

Many ARM template samples do use SAS URLs, but always as a parameter. But how can you supply a parameter to a resource that might not yet exist? That’s the whole point of using the template.

So, the only option is to configure the Web App Service after running the deployment.

The solution

For this solution, we use PowerShell. This makes it easy for running this code in a VSTS or TFS release pipeline. But it can be used in any way you want to configure your environments.

Depending on how you run this script you might need to login first using Login-AzureRmAccount and select the Azure Subscription you want to use using Select-AzureRmSubscription.

The configuration is done in 6 steps.

  1. We get the Storage Account where we want to store the Application Logs.
    $sa = Get-AzureRmStorageAccount -ResourceGroupName "loremipsumresourcegroup"
                                    -Name "loremipsumstore"

  2. We make sure there is a container to store the logs. Because we can run the script multiple times, we ignore the error if the container already exists.
    New-AzureStorageContainer -Context $sa.Context
                              -Name "webapp-logs"
                              -ErrorAction Ignore

  3. Next, we generate the SAS token for the container. We use the same settings Microsoft uses when creating the link using the Azure Portal.
    $sasToken = New-AzureStorageContainerSASToken -Context $sa.Context
                                                  -Name "webapp-logs"
                                                  -FullUri
                                                  -Permission rwdl
                                                  -StartTime (Get-Date).Date
                                                  -ExpiryTime (Get-Date).Date.AddYears(200)

  4. We want to update the AppSettings as the configuration is stored there. But when you update the AppSettings, any setting not present in the update will be removed. Therefore, we first want to get all the existing AppSettings.
    $webApp = Get-AzureRmWebApp -ResourceGroupName "loremipsumresourcegroup"
                                -Name "LoremIpsumWebApp"

  5. Strangely the Set-AzureRmWebApp command does not accept the SiteConfig.AppSettings we got from the Get-AzureRmWebApp command. We need to create a Hash Table for this.
    To make sure the Application Settings keep the same order, we define the Hash Table as Ordered.

    $appSettings = [ordered]@{}
    $webapp.SiteConfig.AppSettings | % { $appSettings[$_.Name] = $_.Value }
    $appSettings.DIAGNOSTICS_AZUREBLOBCONTAINERSASURL = [string]$sasToken
  6. Now we can update the App Service using the Set-AzureRmWebApp command.
    Set-AzureRmWebApp -ResourceGroupName "loremipsumresourcegroup"
                      -Name "LoremIpsumWebApp"
                      -AppSettings $appSettings

Source code

The complete source code is available as GitHub Gist: Configure­AppService­ApplicationLog­To­BlobStorage.ps1 for reference.

2 Comments

  1. /

    Hello Michael,
    unfortunately setting up these two variable in appsettings is not enough to get Diagnostic working andactive.

    When you reach the configuration on Get-AzureWebsites, you still have the AzureBlobTraceEnabled set to False AzureBlobTraceLevel to default "Error" value.
    I was not able to automate the set of these two parameters, Set-AzureWebsites does no longer enable this parameter.
    Do you have any hint?
    XAvier GADEFAIT

  2. /

    Hi,

    Xavier is right, unable to set it. Still in Disabled (set but not enabled in other words)

Leave a comment