Jez
Jez

Reputation: 30071

Providing an Azure web app with complex settings configuration

I'm using appsettings.json in my ASP.NET Core web application to provide configuration values to my application. Some of the configuration is more complex than just "name/value pairs", such as the Serilog configuration:

"Serilog": {
    "MinimumLevel": {
        "Default": "Information",
        "Override": {
            "System": "Warning",
            "Microsoft": "Warning",
            "Microsoft.Hosting.Lifetime": "Information",
            "Microsoft.AspNetCore.Authentication": "Information"
        }
    },
    "Enrich": [ "FromLogContext", "WithMachineName", "WithThreadId" ],
    "WriteTo": [
        { "Name": "Console" },
        {
            "Name": "File",
            "Args": {
                "path": "C:/Development/logs/log-auth.txt",
                "fileSizeLimitBytes": 1000000,
                "rollOnFileSizeLimit": true,
                "shared": true,
                "flushToDiskInterval": 1,
                "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level:u3}] {SourceContext} | {Message:lj}{NewLine}{Exception}"
            }
        }
    ]
}

What I want to know is, how can I provide my Azure web app with this configuration? I know I could create an appsettings.Production.json file and push that when I publish, but what is the point in deploying settings with a publish? They might as well be hard-coded. The point of a settings file is that you should be able to change settings and restart the app, changing its behaviour, with no code re-deployment.

The only thing I can see provided by Azure is its "Settings | Configuration" section in the portal, but these settings are only allowed to be simple name/value pairs. My Serilog configuration is not valid there. So how can I provide any kind of advanced configuration?

Upvotes: 3

Views: 1309

Answers (2)

Martin Brandl
Martin Brandl

Reputation: 59031

As Thiago already said, you can add more then simple key/value configuration using :. However, if you have to deal with larger application configurations I would suggest using Azure App Configuration.

On Linux-hosted web apps, Azure won't allow you to insert colons into configuration settings presumably because it's not allowed in Linux environment variable names. Instead of colons, use double-underscores (__).

See also: Import or export configuration data

Upvotes: 4

Thiago Custodio
Thiago Custodio

Reputation: 18362

the appsettings.Production.json file is ignored during the publish. You need to use powershell or CI/CD (using Azure Devops for example) in order to define the settings.

About the key/value pairs, you can specify complex types using ':' as the separator For example:

Serilog:MinimumLevel:Default

I've been using the following powershell script:

$appname = "name of your function app"
$rg = "name of resource group"
$webApp = Get-AzureRmwebApp -ResourceGroupName $rg -Name $appname
$webAppSettings = $webApp.SiteConfig.AppSettings
$hash = @{}
foreach ($setting in $webAppSettings) {
    $hash[$setting.Name] = $setting.Value
}
$hash['Serilog:MinimumLevel:Default'] = 'Information'
$hash['Serilog:MinimumLevel:Override:System'] = 'Warning'
$hash['Serilog:MinimumLevel:Override:Microsoft'] = 'Warning'
$hash['Serilog:MinimumLevel:Override:Microsoft.Hosting.Lifetime'] = 'Information'
$hash['Serilog:MinimumLevel:Override:Microsoft.AspNetCore.Authentication'] = 'Information'

$hash['Serilog:Enrich:0'] = "FromLogContext"
$hash['Serilog:Enrich:1'] = "WithMachineName"
$hash['Serilog:Enrich:2'] = "WithThreadId"

$hash['Serilog:WriteTo:0:Name'] = "Console"
$hash['Serilog:WriteTo:1:Name'] = "File"
$hash['Serilog:WriteTo:1:Args:path'] = "C:/Development/logs/log-auth.txt"
$hash['Serilog:WriteTo:1:Args:fileSizeLimitBytes'] = "1000000"
$hash['Serilog:WriteTo:1:Args:rollOnFileSizeLimit'] = "true"
$hash['Serilog:WriteTo:1:Args:shared'] = "true"
$hash['Serilog:WriteTo:1:Args:flushToDiskInterval'] = "1"
$hash['Serilog:WriteTo:1:Args:outputTemplate'] = "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level:u3}] {SourceContext} | {Message:lj}{NewLine}{Exception}"


Set-AzureRMWebAppSlot -ResourceGroupName $rg -Name $appname -AppSettings $hash -Slot production

PS: double check the settings / values after the execution...

Upvotes: 4

Related Questions