As any good deployment architect would tell you, when you are creating a brand new system (or cleaning up an old one) there needs to be an environment for production (your polished, tested, and robust system), for testing (where you physically shot put the kitchen sink at your code), and for your development (also called your “sandbox”, because you sometimes get so frustrated with your code that you wonder if it’s as futile as a child trying to communicate through a plastic phone). Branching strategies are described abound in the internet world, but I ran into a particular issue recently with Azure .
Azure is still pretty new in the development game. As a cloud based system, right now the majority of its users are thinking of it as a way to host their VMs with some bonus features. In the system I’m working on, it’s individual entities that are connect to each other through API calls, queues, and the like. It’s not all on one system, and it’s hard to keep track of the millions (literally in our case) of ways of communications for end to end. Azure’s solution to this problem? Azure Resource Manager, or ARM templates. In reality, they’re a series of JSON files that a powershell script runs on top of in the Azure deployment space. There’s a template file where you state what items you want (“I would like 2 service bus queues, a web-app, a logic app, and a side of fries please.”) and a parameter file where you can specify arguments such as names and resource locations.
That second file is key to our success in the deployment world for Azure. Because we want an identical system for our testing or development world as our production world (well, there is always the “we’ll do it live!” approach) we just plug in a different resource group to put our stuff (If you don’t know what a resource group is, it’s mostly a logical selection of entities in Azure. 99.9% of the time you want your stuff to be in the same location since, well, no one ever said they wanted a slow code base) . One is in production, one is for development. You can then specify if you want to create these objects in your production world, or your development world.
Now for the code, not the resources they live on that ARM deploys (as in, ARM deploys the website, you have to upload the cat videos), for web config files, it’s well documented how to specify if you want a setting or connection string to point to your dev or prod address (say, for a SQL table). But what about app.config files? How do we do that?
After a few days of pulling out my hair, I figured that out the fun way. Enter stage left, SlowCheetah.
This NuGet package and Visual Studio extension combo allows for custom transforms of your config files, and they had released a version for Visual Studio 2015 one month before this problem showed up (phew). It’s well documented of making a transform, but I’ll walk through the steps here of how I fixed it for app config files in Azure.
Tutorial Time, My Friends.
Second, right click your app.config file in VS, and create new transforms.
If you’re using the default configurations, you should now see a Debug and Release config (you’ll see as many as you have configurations setup for this project).
Now make your changes in your release or debug configurations as documented in SlowCheetah’s tutorials. For us, we made the release our “production” config, and debug our “dev” config.
Third, here’s the step that caught me up, you have to tell Azure to include your new transformed app config. If you did this with web config files in Azure, you’d be all fine and dandy. However, it will not be included if you did an app.config change. We ran into this problem a lot with Azure, specifically for things like Azure Functions (a name which has confused many), aka a really thin one class C# program. Specifically in that case, Azure gives you a strange GUI to change app config settings, which was a pain for someone like us who wanted to add a non standard connection string (for Entity Framework). We ended up having to make a DAL style .dll file and uploading it.
So, to include your app.config in your build, unload your .cproj or open it up in a notepad style editor. Add the line to include or that it depends on a specific config file for the configuration you wish to use this config for (i.e Release or Debug). Find the PropertyGroup for the release that you need to have a different config file for, and include this line:
Fill the * with your release value. Here’s what the xml should look like now:
Finally, in your build definition for Azure deployment, include your configuration argument for the configuration you want to use. In theory, you should have a build definition per environment (test, dev, prod, etc), and it is just another msbuild argument.
Here’s what ours looked like:
There you have it. You now can have multiple app.config files for your code when you deploy.