Working with Azure App Services Application Settings and Connection Strings in ASP.NET Core

ASP.NET Core’s configuration system has been re-architected from previous versions of ASP.NET, which relied on System.Configuration and XML configuration files like web.config. The new configuration model provides streamlined access to key/value based settings that can be retrieved from a variety of sources: from files using built-in support for JSON, XML, and INI formats, as well as from environment variables, command line arguments or an in-memory collection.

Azure App Services gives us the possibility to set these settings directly in the Azure Portal and retrieve them from our Application Code:

figure1

App settings

This section contains name/value pairs that you web app will load on start up.

  • For .NET apps like the previous versions of ASP.NET, these settings are injected into your .NET configuration AppSettings at runtime, overriding existing settings.
  • These settings also are injected as environment variables at runtime. For each app setting, two environment variables are created; one with the name specified by the app setting entry, and another with a prefix of APPSETTING_. Both contain the same value.

Connection strings

For .NET apps like the previous versions of ASP.NET, these connection strings are injected into your .NET configuration connectionStrings settings at runtime, overriding existing entries where the key equals the linked database name.

These settings will also be available as environment variables at runtime, prefixed with the connection type. The environment variable prefixes are as follows:

  • SQL Server: SQLCONNSTR_
  • MySQL: MYSQLCONNSTR_
  • SQL Database: SQLAZURECONNSTR_
  • Custom: CUSTOMCONNSTR_

For example, if a Custom connection string were named Redis, it would be accessed through the environment variable CUSTOMCONNSTR_Redis.

We can see these environment variables through KUDU: https://<sitename>.scm.azurewebsites.net/Env.cshtml

Getting these settings from ASP.NET Core

UPDATE: Jeff Sanders wrote an excellent blog explaining how to get these settings and work with them directly from your controllers in an elegant and simple way: Azure .NET Core Application Settings

The way to get these settings from our ASP.NET Core is accessing to the injected environment variables. Hence we have to load these environment variables into our Configuration in the Startup.cs file:

        public Startup(IHostingEnvironment env)

        {

            var builder = new ConfigurationBuilder()

                .SetBasePath(env.ContentRootPath)

                .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)

                .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)

                .AddEnvironmentVariables();

            Configuration = builder.Build();

        }

 

The order in which configuration sources are specified is important, as this establishes the precedence with which settings will be applied if they exist in multiple locations. In the example below, if the same setting exists in both appsettings.json and in an environment variable, the setting from the environment variable will be the one that is used. The last configuration source specified “wins” if a setting exists in more than one location. The ASP.NET team recommends specifying environment variables last, so that the environment where your app is running can override anything set in deployed configuration files.

Grouped in sections

In ASP.NET Core we can group our related settings in sections, one group for the connection string, another one for Application Insights configuration, another for  AzureAD...

An example of appsettings.json file would be:

figure2

If we want, for example, to retrieve the AzureAD's ClientId we could get it through our Configuration: Configuration["Authentication:AzureAd:ClientId"] or the Application Insights' InstrumentationKey: Configuration["ApplicationInsights:InstrumentationKey"]

Overriding nested keys in Azure App Services (through environment variables)

To override nested keys in the App Settings section we can define a variable using the full path Authentication:AzureAd:ClientId as name or using double underscore Authentication__AzureAd__ClientId

Connection Strings

To get the connection string named "Redis" defined in the appsettings.json file we could just use the same approach that we used earlier: Configuration["ConnectionStrings:Redis"].

However there's a better way to access to the connection strings, an extension method Configuration.GetConnectionString("Redis") which when is loading the keys from the appsettings.json file is just acting as a Shorthand for the ConnectionStrings section but when is working with the environment variables that Azure App Services defines for the connection strings is able to locate the "Redis" connection string regardless of the type the connection string has in the portal: SQL Server, MySQL, SQL Database or Custom.

So we can use Configuration.GetConnectionString("Redis") to get a development connection string from our appsettings.json file and override it setting a different one in the Connection String panel of our Web App when the application is deployed and running in Azure.

 

May the PaaS be with you!

Carlos.