It seems that my recent post about the sanctity of test environments was appreciated more than I expected, so I’ve decided to address another topic that too frequently gets misunderstood or which importance is usually neglected:
Basically, there are to two categories of configuration:
- business (functional) configuration
- technical (non-functional) configuration
The easiest way to distinguish between those two is by finding out, who’s authorized to do the actual change. The separation should be VERY clear. For instance: business configuration should be changed only using the rights and privileges that make sense for business-oriented people. But this time, I’ll focus on technical configuration only.
Let’s start with bold statements:
- The medium where configuration is kept doesn’t matter much for the considerations below. Surely it has to make sense in general, but all the rules apply to config in files, config in DBs, etc.
- Common sense rights apply here as usually, so: watch for information redundancy, pay attention to what’s needed to actually apply the configuration change once it’s done in the medium, etc.
- Tech configuration is an artifact. Its maintenance has to follow exactly the same rule other artifacts do - for instance it has to be put in version control and every configuration change has to go through development process (whatever it means for you: QA, staging, automated deployment, acceptance, peer review, etc.).
- Split your technical configuration in 2 parts: static and dynamic one. Static (we usually call it "templates") is the part that doesn’t change between environments (various test envs, prod, etc.) and dynamic (we tend to name it "tokens") is the rest (server names, IP addresses, port numbers, tech user names, etc.). Why so? To make sure that you have in full control the difference that IS ALLOWED to occur between different environments. How to control them (those changes) then? By automated creation of configuration in continuous deployment process - merging the static and dynamic part for every environment (in other words - substituting placeholders in templates with token values).
DOs and DON’Ts
Never ever allow manual changes in tech configuration - it may go w/o consequences if you have a simple, one-node, one-layer application on one environment. But once it grows up, how will you control and propagate the changes? So many things may fail here:
- you’ll forget to change the configuration on one of your nodes
- the service endpoint you use is used in a different context for other app (as a client endpoint) and you somehow skipped that
- hotfix or release may overwrite whole configuration file, so you can lose your tweaking
- if you decide never to overwrite, but always do manual adjustments instead, you’re aiming for a very error-prone path; what’s even worse - this is totally against the deployment automation
- exceptions tend to evolve to habits faster than you think
If you don’t treat your tech configuration as artifact and the config changes do not follow the development process, it gets totally untraceable and non-transparent:
- "hey, this setting is wrong! who put it here and why?" "dunno, will have to check my mailbox"
- "we copied that from your MS Word manual, who could expect that the codepage will be messed if we paste it into terminal window?"
About being strict
"But what’s wrong in making an exception once or twice? We just have to change the configuration and we have to do it fast!"
Exceptions and overridance sucks big-time:
- People forget about your exceptions and “cheats” two days after that happen. Later they are just the main cause of errors and unexpected behaviors - as a result, everyone loses the confidence in test / prod environment’s stability and predictability.
- Sooner or later the automated deployment will overwrite the manual tweaks - the question is: will it be intended or not? Will the necessary changes be present in automated deployment artifacts as well?
- If we do something that simple as configuration change manually, it means that either: we don’t understand that we can do it in fast and reliable way automatically or our continuous deployment sucks. But even in the 2nd case, it doesn’t mean we should neglect CD - remember the CD’s 1st law: "if something hurts, do it more often". Kaizen FTW.
Q.: With all those restrictions - does it really make sense to have configuration then, if it’s such a pain in the @ss?
A.: Of course it does! Remember that even if configuration tokens are maintained in version control, modifying them is still something different than modifying code - it’s easier to read for everyone (not just devs), it’s modifications involve only (Dev)Ops people and the range of artifacts to be re-deployed is very limited.
Q.: It’s just files, aren’t they meant to be modified manually anyway? Aren’t we overtechnicizing for dogma’s sake?
A.: Sorry, you didn’t get anything I’ve written above. Read the blog post once again. But first, try to find a difference between:
- manually adjusting config file and copying a single DLL with a fix made and compiled by one of devs
- possible negative effect (on the environment) of broken configuration and broken library / executable
- a need to test change in code and change in configuration