Azure Deployment Slot Connection String

If you’ve deployed a website to Azure using App Services, you know you can override app settings and connection strings in the web.config using environment variables. This is a very handy feature since you can scrap web.config transforms all together if these are the only areas you need to touch.

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. To configure an app setting or connection string to stick to a specific slot (not swapped), go to the Configuration page for that slot. Add or edit a setting, and then select deployment slot setting. Selecting this check box tells App Service that the setting is not swappable. As you may know a Deployment Slot setting has a marking option called “Slot Setting”. This means that the setting is sticky to the slot that gives you the option to keep settings specific for a specific environment. Take for example your production connection strings.

Since ASP.NET Core does not use web.configs, at least not in a traditional way, how do we override these settings now? Well, pretty much in the exact same way, just with a different format. First let’s look at the new appsettings.json file that will be in your Core app:

Deployment slots or Azure slots are actually instances of Azure Web Apps which are tied to that website. A deployment slot will carry the name of the Azure Web App + SlotName. For example, if my Azure Web App is called DebDemo and I create a slot called staging, then my slot will be an Azure Web App with the name DebDemo(staging) and its url. Azure can be scripted to update the secrets on a timer - so in case a connection string gets in to the wrong hands, it is only valid for a day (or a week, or whatever) In case the secret is shared between multiple applications, you only have to update it in one place (not the greatest benefit, but still nice).

{
“Logging”: {
“IncludeScopes”: false,
“LogLevel”: {
“Default”: “Debug”,
“System”: “Information”,
“Microsoft”: “Information”
}
},
“ConnectionStrings”: {
“ConnectionString1”: “localhost-connection-string”
},
“AppSettings”: {
“Environment”: “localhost”,
“NonSlot1”: “localhost1”,
“NonSlot2”: “localhost2”
}
}

In this example, I simple have a Logging section (in there by default), a ConnectionStrings section (this must be named ‘ConnectionStrings’ if you truly want to use it as such), and an AppSettings section (you can name this anything, but I like to keep it familiar).

To override these in your Azure App Service web app, simply navigate to your web app in Azure (or the deployment slot, as in this image), and open up the Application Settings and scroll down to the App Settings and Connection strings sections.

Connection Strings

Connection strings are simple. Since Core encourages you to use a section called ConnectionStrings and only put connection strings in it, you can simply reference the connection string name without any other gunk on it.

App Settings

With app settings we have to craft the key name to match the structure of the json file. So:

“AppSettings”: {
“Environment”: “localhost”,
“NonSlot1”: “localhost1”,
“NonSlot2”: “localhost2”
}

Becomes:

  • AppSettings:Environment
  • AppSettings:NonSlot1
  • AppSettings:NotSlot2

You simply add a colon between the parent and child items. A double underscore also works: AppSettings__Environment.

Deployment

What’s nice about this is, we can now have nested app settings (if you like) and easily reference them using this new structure and naming convention:

“AppSettings”: {

“AwesomeSettings”: {
“Environment”: “awesomehost”,
“NonSlot1”: “awesomehost1”,
“NonSlot2”: “awesomehost2”
}

Azure deployment slot connection string example

“CoolSettings”: {
“Environment”: “coolhost”,
“NonSlot1”: “coolhost1”,
“NonSlot2”: “coolhost2”
}

}

Azure Deployment Slot Connection String Example

This would look like:

  • AppSettings:AwesomeSettings:Environment
  • AppSettings:CoolSettings:Environment

Very cool stuff! For more reading check these posts out:

21 Aug 2018Azure Deployment Slot Connection String

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:

Connection
  • the appsettings.json file; and
  • the environment variables

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:

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

Azure Deployment Slot Connection String Functions

Type of connection stringPrefix
SQL ServerSQLCONNSTR_
MySQLMYSQLCONNSTR_
Azure SQLAZURESQLCONNSTR_
CustomCUSTOMCONNSTR_

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?!

Azure Deployment Slot Connection String Function

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.

Azure Connection String Deployment Slot Setting

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

Azure Deployment Slot Connection Strings

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.

Azure deployment slot connection string functions

Related Posts