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:
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:
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
- 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.