Azure App Service connection strings and ASP.NET Core - How?!

Here’s a quick one. You know how in ASP.NET Core there’s this new configuration model where you can get values from different providers? If not, I suggest you read the official documentation on it which is absolutely great!

A primer

For the purpose of this post, let’s imagine an ASP.NET Core MVC application that reads configuration from these sources:

The order matters here, because if several providers export the same value, the last one wins. In our case, imagine that the JSON file is the following:

 {
   "ConnectionStrings": {
     "SqlConnection": "Data Source=server; Initial Catalog=database; Integrated Security=SSPI"
   }
 }

Let’s also imagine that we have an environment variable called CONNECTIONSTRINGS:SQLCONNECTION with the value Data Source=different-server; Initial Catalog=different-database; Integrated Security=SSPI.

In that case, the value coming from the environment variable wins and will be the one returned from the configuration.

On to our interesting case

Azure App Service allows you to specify both application settings and connection strings so that you don’t need to deploy your application again if you want to change some configuration settings.

The documentation states that connection strings will be exposed as environment variables which will be prefixed based on which type of connection string you create

Type of connection string Prefix
SQL Server SQLCONNSTR_
MySQL MYSQLCONNSTR_
Azure SQL AZURESQLCONNSTR_
Custom CUSTOMCONNSTR_

My colleague Dom had an ASP.NET Core web application deployed to an Azure App Service. This application was sourcing a connection string from the ConnectionStrings:SqlConnection configuration key.

I was very surprised when he created an Azure SQL connection string named SqlConnection in his App Service and his app used it to connect to his Azure SQL database!

If we follow the docs, the environment variable corresponding to this connection string would be named AZURESQLCONNSTR_SQLCONNECTION. It was the case as we double-checked that in the Kudu console where you can see all the environment variables of your App Service.

So how did it work?!

I know. Much confusion. My understanding was that only an environment variable named CONNECTIONSTRINGS:SQLCONNECTION would override the one that was present in the appsettings.json configuration file.

What next? Lucky for us, all that configuration code is open-source and available on the aspnet/Configuration repository on GitHub. This contains both the abstractions and several providers: JSON, XML and INI files, environment variables, command line arguments, Azure Key Vault, etc…

Next step is digging in the environment variables provider to see if there’s anything of interest. And there is! Having a look at the EnvironmentVariablesConfigurationProvider class, it all falls into place.

The provider checks for all the prefixes present in the table above and replaces them with ConnectionStrings: when feeding the data into the configuration model. This means that an environment variable named AZURESQLCONNSTR_SQLCONNECTION is fed into the configuration system with the ConnectionStrings:SqlConnection value. This explains why creating a connection string in the Azure App Service made the application change its connection string.

I’m happy because I learnt something new.

Bonus

I actually learnt something else. Double underscores in environment variables will be replaced by the configuration delimiter, :, when fed into the configuration model. That’s shown by the NormalizeKey method. This means that if we were not using Azure App Service, we could override the connection string with two environment variables: ConnectionStrings:SqlConnection and ConnectionStrings__SqlConnection.