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.

Comments

  • Anonymous
    October 30, 2016
    Thanks Carlos! I couldn't find anywhere (until I found your post) how to set the environment variable when it's nested in the appsettings.json! It certainly needs clarifying in the documentation.
  • Anonymous
    February 03, 2017
    This is quite possibly the most helpful article I have ever read in my entire life. I have been trying to figure this out for forever. Thank you!
  • Anonymous
    March 04, 2017
    I couldn't have said it better than @FloydThe documentation just says it gets injected... how is the huge question... double-underscore, who would have thoughtOnce I finally get me blog up, this post will be my first pingback :)Thanks so much, your awesome!
  • Anonymous
    March 22, 2017
    Really nice article. What i'm confused about is where i call the Configuration.GetConnectionString("Redis")? If i have an ASP.NET Core Web API app and wants to use Entity Framework Core, where do i define what connectionString it is getting the data from and post to?
    • Anonymous
      June 03, 2017
      @Jonas: You need to define the connection string of the production resources in the azure app service settings(in azure portal). But to test it in development phase you can define it in appsettings.json with the same name. So, the code doesn't have to change at all. At run time depending on the environment, it will pick up the development or production connection string. This is the problem this approach is trying to solve. This is not just for connection strings but for any configuration to the app specific to environment.
  • Anonymous
    April 29, 2017
    Thank you!!!
  • Anonymous
    May 24, 2017
    Good job, you brought brightness to Azure documentation mess. Thank you very much!Microsoft should use this article as template for whole Azure documentation.
  • Anonymous
    July 25, 2017
    Nice article :)
  • Anonymous
    April 11, 2018
    Good article! Saved me a lot of time.