Environmental Config Files

I came across something disturbing recently and I want to get my two cents on the table because this isn’t the first time it’s come up. Several components in the project I’m assigned to store various configuration attributes in text files. Whether they’re name-value (properties) files or XML data, this is a good choice because it allows the customization of application behavior without code changes or redeployment … if you do it properly.

What I encountered in several places is a conf directory which contained subdirectories which resemble the following: /local, /dev, /test, /stg, /prod.

At first glance, this looks completely reasonable especially if you consider that each corresponding environment declares a container-level variable whose value is one of the directory names (Development/Integration=dev, UAT/Test=test, etc.). Developers get to configure each environment and at deployment time the server simply knows how to behave based on the preset environment variable. Sounds OK, right?

NO! It isn’t OK. It is horrible and you should never do it. Packaging configuration in with code leaves the System Administrator powerless to administer the system. See the problem? No? Here are more reasons:

  • Configuration changes require a redeployment of the application (possibly even repackaging)
  • Developers may not (indeed, should not) be privy to certain config information (passwords, let’s say) for production environments
  • Test environments of the same “level” can’t have differing configuration unless you jump through hoops like branching source code
  • Turning a dev/test/stage box into a production one (or vice versa) with one small change is just scary
  • A developer can change production and nobody will notice until the code gets to production!
  • A developer can change production and nobody will notice until the code gets to production!
  • A DEVELOPER CAN CHANGE PRODUCTION AND NOBODY WILL NOTICE UNTIL THE CODE GETS TO PRODUCTION!

Get it?

The way to manage configuration is to provide a nicely-commented prototype config file (that can’t/won’t be read) with your application and leave the runtime configuration in a file outside the deployed application path. There are many ways to make such files available to your program regardless of whether you’re using a container or not. You can:

  • Add a conf directory to the runtime classpath
  • Put the config files in a known directory such as common/classes on Tomcat
  • Jar them up and name them according to environment, if you just absolutely must not let the admins touch them.

Any of these tactics work. As long as you aren’t marrying code and configuration, you can’t miss.

Comments are closed.