Paul Gielens:ThoughtsService

another Endpoint to my thoughts

News

Syndication

Ads


Favorites

Projects

.NET Configuration Hell

Modify the configuration files every time you deploy in a new environment. This is a task often performed by the operations department and is time consuming and error prone. We tried to regain control on the situation by documenting this process thoroughly. Although our effort helped with the communication between the development team and the operations department to be more effective, the overall result is not what we hoped for. Eventually the operations department ends up with maintaining separate copies of configuration files in different locations on the staging servers. This means configuration knowledge is kept outside of the source control system. The side effect of this is that when you make changes, you need to make changes to every file in every location. We also tried to maintain separate files with different names such as development.config, test.config, acceptance.config, production.config. What brought us a step closer in the right direction is to split the configuration files in aspect areas such as developmentData.config, testData.config etc and although making changes is now less intrusive this does not solve the maintenance burden for the operations department. Certainly we experimented with the Enterprise Library configuration block and build our own plug-ins for the configuration tool.

Where do we stand today with configuration management? With over four hundred applications in production not to mention the number of projects in staging at the moment, operations department is struggling to stay on top of things.

How does your organization cope with the configuration associated with .NET? What are your experiences? Do you use tools?

Comments

Rich Gavel said:

We create install exe's out of our automated build process which install a template .config file and modify it based upon a environment specific settings file chosen during the installation process via a Open File dialog. Though we have had discussions about having just one entry in the .config: a reference to some kind of configuration service to gather all other configuration data (probably off a database).

# April 5, 2007 11:19 AM

RMD said:

We created a database-based configuration library.

The config files basically just contain a DB connection string, a "configuration set name", which allows you to have different configs in the same DB table.

It also has a "valueset" entry which lets you switch up value for staging and production.

In the end, you end up managing all your config values in a database table instead of merging config files. Works great.

# April 5, 2007 12:36 PM

Joe said:

1. Wrote a simple VBScript that changes an attribute value for an arbitrary XML element based on an XPath expression.  Arguments are: filename, Xpath-expression, attribute-name, new value.  Something like:

cscript UpdateAttribute.vbs web.config /configuration/system.web/compilation debug false

2. Use <appSettings file="..."> and (.NET 2.0) the configSource attribute so that different environments have different config files.

# April 5, 2007 1:35 PM

The Other Steve said:

Some configuration settings, I've determined are better stored in a database.  This is mainly because I can then change them through an admin screen instead of touching the web server.(hard to do with our change control process)  But you still have to manage the database connection string.

I began using Loren Halvorson's XmlPreprocess tool.  Hanselman mentioned it here:

http://www.hanselman.com/blog/XmlPreprocessIsAnElegantHackOrTheHackIsInTheEyeOfTheBeholder.aspx

We then maintain a Excel spreadsheet with the configuration values for different environments.  This is in sourcesafe, as well as XML files that are generated from the excel spreadsheet for each environment.  Then in my MSI installer, I prompt for which environment and then call xmlpreprocess and pass in the environment file. (I also prompt for the database password, and pass that in the custom action)

I have to admit, it didn't make a lot of sense at first looking at it.  And I had numerous arguments with my team members.  But once it's in place, it's actually really easy to manage and deploy.

# April 5, 2007 2:17 PM

p.gielens said:

Thanks for all the great answers thus far! We are currently looking into the following options msi installers, application container, configuration (web) service.

# April 5, 2007 3:04 PM

Rich said:

The technique that I use is a class that abstracts the settings, then detects in the environment what the environment (dev, certification, qa, prod, etc.).  I'm fortunate in that the web servers in the company all have a registry setting that describes the environment.

In the one web.config, we have settings for the dev, cert and production connection strings.  However, in the code we just reference it as:

<code>

Settings settings = new Settings();

settings.ConnString; // Abstracted connection string

</code>

The class reads the registry setting, determines the environment and sends back the appropriate setting fof the environment.

If you are using Nant, you can also use the XMLpoke feature to change the config when using different deployment tasks.

# April 5, 2007 4:22 PM

JCube said:

We use a very similar technique as Rich's above. We have one web.config file where we define all environments in configSections. And once deployed to each environment, we flip the switch. This is much less error prone and makes the deployment tasks simpler. For example,

<configSections>

 <section name="dev" type="..NameValueCollection.." />

 <section name="qa" type="..NameValueCollection.." />

 <section name="prod" type="..NameValueCollection.." />

</configSections>

and in <appSettings>, we defined the current environment. <add key="Environment" value="dev" />

Finally we have the settings in the section for each environment.

<dev>

 <add key="ImagePath" value="~/dev/images" />

</dev>

<qa>

 <add key="ImagePath" value="~/qa/images" />

</qa>

Then we have a wrapper class that can read values by simply doing, Settings.ImagePath, which will automatically read the correct value according to the environment mode you set.

# April 5, 2007 9:29 PM

jdn said:

Use a combination of Server Aliases and environment variables (of course, your code has to be set to use these).

That way, you never change anything except the aliases and variables on the machines you deploy to.  Code never changes.

You don't have to multiply (Dev/Qa/Prod) config sections, you don't have to put it in a database (how do you configure which server has the database in the first place), etc. and it lets operations do what they do, configure the servers your apps need to run on.

# April 5, 2007 11:12 PM

Carel Lotz said:

We use MSBuild and custom meta-data. We have created a MSBuild file that has the links to all the different config files.  Each file is tagged with custom environment meta-data (i.e. DEV, TST, QA, PROD).  The build file copies the correct version of the config files by matching the custom meta-data to an Environment property that we pass to the build.  The value for the Environment property can be passed directly when doing the build manually or is read from a file and kept in Subversion for our CI process.  

# April 6, 2007 7:37 AM

thycotic said:

We use a simple naming convention for our web applications:

web.config

web-test.config

web-stage.config

web-prod.config

Unfortunately you have to remember to update each when making new configuration settings but they are all in the solution and under source control.

Our NAnt-based deploy script automatically flips the right configuration file into place when the code is deployed.

# April 7, 2007 7:19 PM

Saber Karmous said:

All our machine have a key in the machine config which describes which "environment" it is (Dev, Test, Prod). And we only have one config file. Our problem is that our operations department has the policy that only operations know what the Production enviroment looks like.

The problem is that most of the developer don't know about good configuration management. Adding, changing or deleting keys from config files seems so easy, but it's a nightmare when you have to regularly deploy your application, and the operations guy wasn't told about the changes because they looked so simple...

# April 7, 2007 7:35 PM

CB said:

I too like the machine config route for the DB connection our boxes just don't seem to move to new environments much. In general I try and keep in mind who the owner of the data is; IT or the customer. For customer data it just needs to be in a place that can be maintained by a GUI.

# May 6, 2007 6:23 PM
Leave a Comment

(required) 

(required) 

(optional)

(required)