Last modified 5 years ago Last modified on 12.09.2012 16:57:55


Version 1.1 is out

New release adds possibility to define parameters for all hosts in full-blown generator environment. Additionally, new version supports --dump-vars command line option, which allows inspecting parameters passed to templates.

Version 1.0 is out

New release changes way of dealing with clashes of service definitions from different groups. Default is old behaviour, but user can change this to merge variables.

Also, the release include some bug fixes.

Version 0.6 is out

Release 0.6 is ready for download and build.

This release introduces new way of calling cfgen, that doesn't need full build environment.


Imagine that you have many servers. Imagine that each of the server holds similar set of services, among the other tasks. These services could be not a critical ones from business point of view, but very useful for you as an administrator. Examples of such services include SSH daemon, mail system (crontab logs anyone?), syslog, backup agent, cron entries or sudo.

Now imagine that you want these services configured similarly across your servers; that the configs on each server are almost-identical. Almost. Differences will probably consist of very few variables, like hostname, LDAP server address and stuff like that. It would be great if you had a sort of template that gets filled with host's parameters just before being used as a config.

This is the place where cfgen appears on the scene.

Main cfgen's use is to mix config templates with host-dependent variables and produce ready-to-use configs, separate one for each known host. Template system used for this is Template::Toolkit, and host-dependent variables are stored in YAML files.

How to download

git clone

How to install

NOTE: Installation process is tested for building packages. If you want to make mess in your system by omitting package system, you are on your own.

You need casual package building tools for your distribution, either rpm-build (RPMs) or dpkg-dev with fakeroot (DEBs).

Red Hat

  1. Prepare source RPM (non-root privileges are fine here)
    make srpm
  2. Build binary RPM (unless you've taken care of building as non-root, you need to be root here)
    rpmbuild --rebuild cfgen-*.src.rpm
  3. Install package with its dependencies (exact path should be printed by previous step); most probably it will be located in /usr/src/redhat/RPMS/noarch/cfgen-*.rpm


  1. Build binary package
    dpkg-buildpackage -b -uc
  2. Install package (../cfgen_*.deb) with its dependencies

How to use

cfgen provides way of thinking of servers, services and configs:

  • Each server has a name.
  • Each server hosts a number of services.
  • Each service has number of configuration files.
  • Particular config file for a given service on two different servers is similar, except for host-specific parameters (like hostname, default gateway or address of used LDAP server). Because of this, config file edited by sysadmin is decoupled from such parameters.
    • file is called a template and uses syntax of Template::Toolkit
    • parameters for server are saved in YAML files
    • each server gets own config files generated from templates
  • YAML files together with templates are called sources.
  • Sources get compiled to actual configs.

There are two approaches (known to me) for generating configs. They differ on where to generate configs:

The former approach has a benefit of not having cfgen to be installed on every machine. This is something good for typical servers.

The latter approach can be used to override some parameters with something stored locally on the machine. This could be useful for maintaining workstations: give users default set of configs, but enable them to tweak settings on their own. This way your users will be cooperating instead of struggling with you, all that without replacing your careful configuration files with something totally out of your control.

Full-blown generator environment

You need to start with an empty directory. Create following directories:

mkdir hosts
mkdir templates
mkdir ready_configs

Now create cfgen.yaml file (name doesn't matter much; this one is just convenient and descriptive) with following contents:

host_data: hosts
config_output_dir: ready_configs
template_dir: templates
#  - nothing yet

Now define some hosts, let's say basalt, granite and sandstone:

echo "--- {}" > hosts/basalt.yaml
echo "--- {}" > hosts/granite.yaml
echo "--- {}" > hosts/sandstone.yaml

Here you go, you have three known hosts. They have no host-specific variables yet.

Last of all, templates. This is a little more work. You need to create templates/config.yaml file (this time name does matter). It lists services that can be defined in hosts' files. Let's define a service named dummy_file:

  - dummy-file.txt

It says that configs for service dummy_file consists of single file called dummy-file.txt in templates directory. Create it with following contents:

This is a dummy file for host [% hostname %].

Variable foo from this service has value "[% %]".

This host has following siblings:
[% FOREACH h IN global.keys.sort -%]
  - [% h %]
[% END -%]

You can now define which hosts have which services (a host needs to have at least one service, either explicitly defined in hosts/* file or implicitly as always_include in cfgen.yaml). Each host file fill with this:

  foo: some contents

Now run cfgen -v cfgen.yaml to generate configs. Check out ready_configs directory to see what was generated.

For more examples see man cfgen.

Template examples


  • Bacula: director and clients
  • firewall script
  • Nagios
  • ...

Quick (single-shot) run

This way of running cfgen is not that quick in the long run, but if you want just to check if your Template::Toolkit construction works, it's good enough, yet you don't have to prepare full build environment. Also, I've seen a use of this method for maintaining users' workstations.

TODO; check man cfgen for now.