0
votes

I'm trying to combine a environment-specific variables in source code to an existing configuration of an App.config-file and AppSettings and ConnectionStrings in Azure App Services for an Azure WebJob (.NET Framework). Having all environment variables in App Services can be quite time-consuming when making changes.

After going through a bunch of blogs and posts on the subject of App.config-tranformations and Azure WebJobs it seems like adding a ConfigurationBuilder is fairly recent way to override environment specific (non-secret) settings. If I'm not mistaken it was added in .NET 4.7.1. It seemed more promising than SlowCheetah and scripting.

But after adding a custom ConfigurationBuilder (similarly to mentioned on link 1) the app settings specified in app service were no longer included in the result. I ended up with only entries from app.config-file and custom ConfigurationBuilder. Do I need to retrieve these app setting while making custom entries in the configuration entries? Or should I expand the EnvironmentVariables and modify those XmlNode-entries?

  1. https://jeffreyfritz.com/2017/11/modern-configuration-for-asp-net-4-7-1-with-configurationbuilders/
  2. https://docs.microsoft.com/en-us/dotnet/api/system.configuration.configurationbuilder?view=netframework-4.7.2
2

2 Answers

2
votes

Take a look at the following links, it seems they address issues similar to what you are describing:

Hope it helps!

1
votes

As it turns out there are a few things to consider and some assumptions to be made before had a possible route to go. I ended up writing my own configuration builder with help of the documentation.

Given that .NETFramework is used and not AspNetCore (specifically .NETFramework 4.7.1 in this case). It seems that App Services provisioned by Azure does use some kind of configuration builder out-of-the-box. It seems like Web.config without any specified configuration builder will include all Azure App Services settings. It will even add settings that aren't present in the Web.config. So scaffolding isn't used; This would probably have made things a tad bit easier to grasp, but Microsoft probably had good reasons for not implementing things that way. Adding a configuration builder of your own will make any settings read from Azure App Services to not be read anymore. Probably, I'm assuming, because you just replaced a "hidden" configuration builder and need to do this work yourself now.

Looking into the source code I did another relevant discovery that help me quite a bit in writing my own configuration builder. There seems to be two typical modes of operation in how configuration builders work: Greedy or "strict". I would advise against using both at the same time. A greedy mode implies that all settings found in, let's say, environment variables are added regardless of whether the key was initially present in Web.config. A "strict" mode implies it only replaces the value for keys present from the start.

I ended up reading relevant settings from the environment variables. But it was a bit tricky to find solid documentation of the appropriate prefixes used (it is possible to read all the variables though). But the most common ones are roughly (I think):

  • APPSETTING_ (believe these correspond to App Services settings, if I recall correctly)
  • SQLServerSQLCONNSTR_
  • SQLAZURECONNSTR_

Anyway, I my particular scenario I was running both an App Service Web App and a WebJob in the same slot. Having settings from the Web App appended for the WebJob seemed unattractive and unnecessary. So I wrote a "strict" configuration builder that cascades all the setting in a careful manner from the sources. This means any setting specified in Azure App Services would also have to be defined in Web.config. If no such setting next any transformed values for a chosen configuration was included. Lastly, the default value value in Web.config was used.

In summary, if you're writing your own configuration builder in .NETFramework, you may need to do a little work to include the App Service app settings or connection strings. You might want to investigate the ConfigurationBuilder-class and their respective methods ProcessConfigurationSection for typed classes or ProcessRawXml and perhaps checkout some real world examples.