Tidbits | Feb. 12, 2006

Application Configuration Best Practices

by Frank Wiles

I signed myself up to write application configuration management into the soon to be released $SUPER_SECRET_OSS_PROJECT. The goal is to have a single default configuration file located on the system (with conf.d/* style includes ) that would define each instance of a particular application.

An instance is simply a name and an easy way for the programmers and admins to talk about each install of a particular application. By simply knowing the instance's name the web application, whether it is a standard Perl CGI or uses FastCGI, mod_perl 1.x, or mod_perl 2.x, can essentially automatically configure itself based on the configuration method preferred by the admin. That's right the admin.

Often there exists a complete disconnect between the programmers and the system administrators responsible for actually making the app run. Programmers want a configuration setup and style that is easy to parse , while sysadmins want a system that is flexible and easy to use.

The configuration infrastructure that I'm building into $SUPER_SECRET_OSS_PROJECT should give everyone the best of several worlds. Here is the idea in a nutshell:

  • You have a central config file let's call it /etc/myconf.conf that will contain a entry for each instance of each application.
  • The instance information will contain either the entire configuration or enough configuration information to bootstrap the config engine enough to gather the rest of the config.
  • The application and any programs or associated cron jobs only need to be given ( via environment variables, command line options, or eek hard coding ) the name of the instance they are a part of to configure themselves.

This is probably best explain with a short example, here is a mock up of the central config file /etc/myconf.conf:

<instance foo>
ConfigViaFlatFile Config::Tiny /etc/apps/foo/foo.cfg 
</instance>


 <instance bar>

ConfigViaParamBuilder Apps::Foo::Params

</instance>

The first instance foo wants to configure itself using the Config::Tiny module and the config information is in /etc/apps/foo/food.cfg

The second instance bar is saying that it wants to configure itself using ModPerl::ParamBuilder
and to use the Apps::Foo::Params module to do so.

So far this is all pretty boring. The real exciting piece is that these two instances could very well be the same code base. One where the admin wants to configure it via custom Apache directives in the httpd.conf and the other using a simple flat text file for configuration. It doesn't matter to the application. You might be asking yourself how that could be. Time for another example:

use SSOP::Conf;   # For Super Secret OSS Project

my $conf = SSOP::Conf->retrieve( $instance );

my $template = $conf->template;

my $dbuser = $conf->dbuser;




 # Or by using a hash reference

my $conf_ref = SSOP::Conf->retrieve_hashref( $instance );

my $template = $$conf_ref{template};

my $dbuser = $$conf_ref{dbuser};

That is all the application needs to know about, the "instance" name,
to configure itself via several methods. Right now the plan is support Config::General, Config::Tiny, PerlSetVars in mod_perl 1 and 2, and ModPerl::ParamBuilder in mod_perl 2.x.

The infrastructure is written so that it doesn't matter to the application how the configuration is gathered and parsed, just so long as it has it. This frees the admin to use whatever configuration method makes the most sense for not only each particular application, but each particular instance of that application.

I think the most exciting aspect is that, provided you use a separately included httpd.conf for each of your instances, your behind the scenes programs, scripts, and cron jobs can share their configuration information. If you like PerlSetVars or ModPerl::ParamBuilder and want all of your app's config to live in your httpd.conf, you don't have to have a separate configuration scheme for your cron jobs.

You're probably saying to yourself, "Why the hell is he telling us this when we can't see the code yet." Well the whole purpose of this entry was to ask all of my readers which configuration file syntaxes they prefer to use, Apache style, .INI style, etc. so we know what to support out of the box. There are plans for a generic SQL backend and LDAP support. The system is built so you can expand on it yourself if there is something we don't support.

Comments, suggestions, rants, death threats, etc. are most welcome. Send them to blog@revsys.com. We want this system to be as useful to as many developers and admins as possible.

2006-02-12T08:00:00 2018-04-18T16:03:35.154833 2006