How To Implement Application Configuration

Workable Approaches to Configuration Management

My starting place is that we should always be striving to ensure that it is difficult to have a syntactically incorrect configuration. In other words, our products should validate configurations before they are accepted. And that has an impact on how configuration should be done.

In the simplest case, an application would start up and checks all its configuration. In this case, it is OK to have configuration stored in files that are edited with Notepad (or some other weak tool) because the application always performs validation of all of its configuration.

Now if an application doesn't always check all its configuration at start-up AND a weak, non-validating tool is used to edit the configuration, then it follows that the application should manage ("gate") the requests to alter any configuration that would otherwise be unchecked. This is especially important for server applications because it is unacceptable for the server not to restart – or to restart with a faulty configuration! This typically means that configuration changes are "submitted" via a process that may reject the changes and then stored the changes elsewhere.

There are a 2 traditional ways to implement configuration control:

  • Via a special configuration editor that is embedded in the application. E.g. a preferences dialog.
  • Via a special editor tool that is independent of the main application. E.g. a control panel dialog.

But these two approaches suffer from the fact that they need extra code and design to deliver a satisfactory UI & that overhead is incurred with every feature that is added to the system. This flies in the face of the fact that configuration is of very low value but collects together changes from all areas of a system. That combination of high cost for very low benefit means that developers are often obliged to augment these 'pretty' solutions with more basic processes. And special tools often need their own configuration, which can make management very complicated.

The next approach is to use a standardised format such as XML or JSON that there exist good editors …

  • Via an off-the-shelf editor tool for a standard/widely used format e.g. Apple’s plist editor.

… XML editors can even style the files they are editing so that they act as very low cost specialised editors. Furthermore, validation is cheaply enhanced by supply a schema. The shortcoming of this approach is that typically they can only pick up syntax errors and not semantic errors.

We can augment the third approach by arranging that the configuration files have to be submitted…

  • Via a file-based submission tool (or drop box) in which the submitted configuration files are considered as requests. E.g. crontab, visudo.

… This can be explicitly via (say) a small command line tool or implicitly via a ‘drop box’. The advantage of a specialised submission tool is that the rejection feedback is nice and straightforward. The advantage of a drop-box submission tool is that the configuration files can be left in place for easy re-editing.

This last approach makes it clear that the configuration files and the data they maintain can be kept completely separately. For example, one might have the configuration specified in (say) JSON but parsed into (say) a SQLITE database for efficient access. As long as there is a straightforward way for the process to report its rejection, this works.

A Bad Example

A bad example of how to do configuration is the Apache web server.

  1. Webmasters edit these files with plain text editors. This basic error means that there’s no assurance of syntactic correctness.
  2. This server reads its configuration files and, if they aren’t to its liking, it may ignore part of the files or fail to start. The basic error is that the working configuration is not cached, so there is pressure to ignore errors and continue with a faulty configuration.
  3. The server reports errors into an error log, the location of which is configured in the config files. The basic error here is that the configuration feedback is muddled up with the runtime feedback so that configuration error feedback is easy to miss and can be difficult to find even if you know what is happening.

A Good Example

By contrast the unix ‘cron’ service is a good example. The cron service executes commands at specified times, rather like an alarm clock. Being time-based there is no safe period in which it can be halted, so they added the ‘crontab’ (cron-table) service for updating the internal configuration (in /var/spool/cron/crontab) behind the back of the running service.

The crontab program is not very complicated. It syntax-checks the input file before copying it into the /var/spool/cron/crontab folder, which functions as the ‘safe checked input’ area, before nudging the running ‘cron’ service to re-read its config files. Because you can recover the original input with crontab –l, you don’t even need to save your copy. If the check fails, crontab reports its complaint straight back out on the command line.

It would be improved if, instead of having a custom input format, crontab used a standardised input format such as XML/JSON along with a schema. And it would be further improved if the configuration was version controlled too, so you could review previous versions.

In a more elaborate application, one way to accomplish this might be to (a) store the versions in a git repository, (b) use a pre-commit hook to perform the syntax checking, and (c) a post-commit hook to do the installation of the new configuration.