Having configuration differences between development and production is largely unavoidable, but it’s important to keep the number of differences to a minimum to avoid unexpected bugs appearing in production that don’t occur in development mode. More than that though, it’s important to minimise configuration.
Configuration is Code
Often things are put in configuration files so that they are easy to change later, often without a full redeployment of the software, but that also implies it can be changed without going through the full testing that a release would usually be subject to. It’s rare for automated tests to cover more than one possible setting for these configuration options so changing them in production is equivalent to deploying completely untested code. What’s worse, it’s quick and easy to do with no audit trail of what happened and when.
These settings should be avoided altogether and the values hard coded in the built product and deployed along with it. That may be as simple as embedding the existing config file in the built software – the aim isn’t necessarily to mix configuration and code, only to remove the options to change the configuration outside of the normal development and deployment process.
For settings that are designed to be changed by the user as a normal part of using the software, make sure that the full range of values is tested, just like any other system input should be.
The most extreme form of configuration is “soft coding” where the system becomes so configurable its essentially a poor-man’s programming language. The Daily WTF has an excellent explanation of soft coding and how even the best of intentions can lead to it.
Dealing with Production Problems
One of the biggest reason people make options configurable by administrators is so that they can quickly reconfigure things to resolve issues in production. Sadly, the worst time you could be making untested changes in production is when things are already behaving in unexpected ways. Instead, make the build, test and deployment process for your software so fast and so seamless that you can make the change in code, fully test it and get it out to production fast enough to resolve the issue. Doing so isn’t easy, but it delivers immense value beyond just resolving production issues. It allows you to more reliably and more rapidly deploy any code change into production. That means spending less time wrangling releases and more time improving the product.