cfgen
Table of Contents
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.
Description
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 http://dozzie.jarowit.net/code/cfgen.git
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
- Prepare source RPM (non-root privileges are fine here)
make srpm
- Build binary RPM (unless you've taken care of building as non-root, you
need to be root here)
rpmbuild --rebuild cronbuilder-*.src.rpm
- 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/cronbuilder-*.rpm
Debian
- Build binary package
dpkg-buildpackage -b -uc
- Install package (../cronbuilder_*.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:
- in one central place; machines only pull compiled configs (I call this a full-blown generator environment)
- on each server separately; machines pull the sources and each of them compiles its own configs (this can be made with single-shot run method)
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 #always_include: # - 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: - 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 "[% dummy_file.foo %]". 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:
dummy_file: 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
TODO
- 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.