This is part of an ongoing series of posts dealing with the practices that will make software deployments boring. Because boring is good!
So far I’ve been saying some pretty standard stuff but this time I want to state a practice that is less-often done well, at least in my opinion.
What to do with configuration files?
I’ve noticed that many people generate configuration information during the deploy. For example, the build output might include a development or master copy of a web.config file, and during deployment the environment-specific stuff gets replaced with the correct information.
I think there’s a better way…
…and that better way is to include the config files for ALL environments in the build. Either keep them all in source code, or go through the “replace elements in the master with the correct values” process, once for each environment. I would tend to go for the latter, since most config files have a mix of environment-specific and non-environment-specific information, and we don’t want to have to maintain multiple copies of the non-environment-specific information. But either way, the build output should contain all the configs.
Earlier I said that every deployment artifact—every artifact—must be generated or assembled during the build and be placed in the output directory of the build. Handling config files in the manner I’ve described is just an example of that. And it comes with real benefits:
- Risk. Selecting the right config file for an environment and putting it in place is in my opinion less risky than walking through a config file making changes to it. So we can do the harder work that may be more error prone during the build, and do the less-risky portion during the deploy. We push risk into an earlier step than deployment.
- Testing/inspection. This is related to managing risk. We should test both the build process and the deployment process, but if we generate config information during the deploy, then the first time we can verify the generation of correct production values is after production deployment! If we generate the configuration information during the build, we can inspect the result at our leisure, as often as we want, with any process we want, before the actual deployment takes place.
In other words, handle configuration files, and any other environment-specific items, just as you would anything else.
…which means we follow the practice of assembling ALL deployment artifacts during the build. Everything that will get deployed should be in the build’s output directory. The fewer exceptions we make to that rule the more we make our deployments boring. And that’s good!