Configuring your application when running in Azure can be a little confusing to begin with, I agree. However, it isn’t really that complicated as long as you understand what config goes where and why.
In Azure, you have 3 places that affect your configuration. Actually it is in more places than that if you count machine.config files and stuff like that, but I’ll ignore that now… And to be honest, it is only 2 places, but you need to tweak 3 places to get it to work…
When you create a new Azure web application project, you get 2 projects in your solution, one “cloud project” and one Web Application Project for example, and both have some form of configuration going.
The cloud project has a csdef-file and two cscfg-files. The csdef-file contains configuration regarding your roles. It defines things like the size of the VM to use, startup tasks that need to run, endpoints to use, certificates and so on. Basically configuring the way the instance(s) run in the cloud.
This information doesn’t necessarily affect you application as such. Your web application does for example not care about what ports it is responding to. These are things that needs to be setup, but generally is unimportant to your actual application.
What is important in this file however, is the ability to add an element called ConfigurationSettings. This element contains <Setting /> elements. These elements define what settings that your config files can, and must, provide. It looks something like this
<WebRole name="MyInstanceName" vmsize="Small">
<Setting name="MyConfigValue" />
<Setting name="MyOtherConfigValue" />
As you can see, it only defines the setting names. It doesn���t contain any of the actual values. The actual values are in the cscfg files, which in this case might look like this
<?xml version="1.0" encoding="utf-8"?>
<ServiceConfiguration serviceName="RecommendationEngine" xmlns="http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceConfiguration" osFamily="1" osVersion="*">
<Instances count="1" />
<Setting name="MyConfigValue" value="Hello" />
<Setting name="MyOtherConfigValue" value="World" />/>
As you can see, it defines first of all how many instances should be running when the application is deployed, but also defines the values for the 2 config settings I defined in the csdef file.
Basically, the configuration settings setup and configured in here, are pretty much like appSettings in your “regular” config-files.
Reading these configuration settings is real easy! Just do this
var cfg = RoleEnvironment.GetConfigurationSettingValue("MyConfigValue");
However, this only works if you are running in the cloud or in the emulator. If you are running your application outside of these environments, you will have to read the config from somewhere else, for example appSettings. This can be done like this
cfg = RoleEnvironment.GetConfigurationSettingValue("MyConfigurationValue");
cfg = ConfigurationManager.AppSettings["MyConfigurationValue"];
You can also manage whether or not you are in the emulator or the real cloud using the RoleEnvironment.IsEmulated property.
I know you probably shouldn’t hardcode things to handle the emulator specifically, but in some cases you have to… At least when you muck about with IoC containers and things, which generally should be configured differently locally compared to in the cloud.
So, why is the information split between a definition and a config? And why are there 2 cscfg-files?
I don’t really know why there is a definition and a config split. It does however mean that we do not need to use config transforms, which is nice. It also means that we can verify that all donfig values are available in all cscfg-files.
The 2 cscfg-files are easier to explain. They are there to offer 2 different configurations. One that is used when deploying to the cloud, and one when running locally. Just in the same way as you can have several configurations using config transforms when running your web application.
The default is to have one for local and one for cloud deployment, but you can add as many as you want. When deploying or packaging your application, you get to choose what config to use
This is the dialog you get when you ask VS to package your application. The top drop-down defines what cscfg-file to use, while the bottom one defines what build configuration should be used when building your application.
Luckily there is a UI for managing these files. Just double-click your role in VS, and you get a window that looks something like this
As you can see, you can add new settings, as well as set the values for the different configurations. Just remember to change the drop-down at the top to set the right config. Changing it like this will update all configurations with that value.
Adding a setting from in here, will automatically create the <Setting /> element in the csdef-file, as well as in the cscfg-files…
Ok, so that is 2 of the three places I mentioned to begin with. What’s the other place? Well, it is where you normally place your configuration, the web.config or app.config file.
The ”normal” config-files are still used. The work in the same way as they always have. They are combined with machine.config and so on, to create a complete set up for your application.
Any custom setting for your application, such as web server settings, webservice settings etc, are all still setup in the web.config or app.config file.
So what is the difference between these locations to store settings in? Well, there are 2 big ones. The first one is the obvious split in what they configure. The csdef/cscfg config is all about configuring the environment that your application runs in. It has got very little to do with configuring the actual application (except for the <ConfigurationSettings />). While the *.config-files are there to configure your actual application.
The other difference is that you can change the cscfg-file at run-time without necessarily restarting the the instance that you are changing. This is not possible in the *.config file. Changing the *.config requires a re-deploy of the application…
Ok…anything else? Well, it might be nice to note that if you need multiple Web.config versions, using config transforms works fine. They however seem to be missing from other projects than “Web Application Project”, so in those cases, you will need something else…
The transforms are not available by default when creating a Web Role, but can easily be added by right-clicking the Web.config and selecting “Add Config Transforms”.
Just remember that the original *.config file will be used when running in the emulator. It is not until your application that the transforms are applied. So in the Azure case, that is when you package or deploy. The config to use is, as mentioned before, defined in the bottom drop-down in the “Package-dialog”
So when should we put things in cscfg, and when should we put it in *.config. Application settings that might change should be in cscfg and not in the <appSettings />. Actually anything that might change at run-time should be in the cscfg. In some cases this isn’t possible, in which case we have to put it in the *.config and re-deploy. In other cases we can listen to changes in the config, and reconfigure the role from code based on the configuration changes. A sample of this can be found here. It is however a bit extreme, a simpler example would be to reconfigure logging levels.
Ok, that should cover most things when it comes to configuring your Azure applications… At least most of the basics. There are more complicated, specific things, but this should get you going…
Once again no code, but I am open for questions and comments…