Following a discussion last week about how the most successful national clubs and societies have evolved, I was amused by a response from someone who professed to setting up the National Procrastination Society. He reckons that this is the most successful society ever because none of the members has so far decided to return their application form, and they haven't yet got around to organizing any meetings.
All of which coincided very nicely with a current period of procrastination here at this tiny and remote p&p location where I now seem to spend all my days writing guidance for Windows Azure. The procrastinated topic was startup tasks and configuration files, and a prolonged burst of frenetic procrastination still hasn't produced a convincing result.
The issue is that you really need to put all your configuration settings for a Cloud Service role in the Windows Azure service configuration file, rather than in web.config or app.config, so that the configuration can be changed without having to redeploy and restart the role. But it's not easy to do. As many blog posts report, several components such as the ASP.NET membership and profile providers, Windows Identity Foundation (WIF) modules, and assorted other bits and pieces aren't "cloud-aware". They only look in the web.config or app.config file.
There is, of course, the new CloudConfigurationManager class that reads from the ServiceConfiguration.cscfg file by default, and falls back to web.config or app.config if the setting is not found in ServiceConfiguration.cscfg. Though it only looks in the appSettings section of web.config or app.config, so it won't find things such as connection strings or WIF settings. We got round this in our guide by wrapping the CloudConfigurationManager class in a custom class that does look in the appropriate locations.
But this is the wrong way round anyway, because what you actually need is for the non-cloud-aware components to look in ServiceConfiguration.cscfg. There's several workarounds described in blog posts and documents to get round the issue by copying values from the service configuration into the current configuration loaded from the web.config or app.config file so that the components can find the appropriate values. The various suggestions include using a separate executable startup task with the AppCmd utility, and by running code in the elevated startup event of a role.
However, all of these are what they say they are: workarounds. None can really be described as "the one true way" that we should recommend in our guidance. So, after the requisite period of procrastination, we've come to the conclusion that we won't include any of them in our reference implementation and just describe the options in the written guidance. Instead we use deployment scripts run from MSBUILD tasks that update the web.config files with the appropriate test or production settings before deploying the package. It seems to be the best plan at the moment - especially as, in an environment that is evolving as quickly as Windows Azure, there may well be a "proper" way just around the corner.
In the meantime I'm off to see if I can remember where I put my application form for the National Procrastination Society. Though I still haven't made up my mind whether I want to join...