Cfengine is a competitor to Puppet, Chef, Ansible, and other configuration management stuff. It is also the oldest one and comes with some theory. Compared to the others, people usually claim that it is harder to learn, but pays off at some point. This is my try to give a useful and pragmatic introduction.

I assume Ubuntu 14.04 LTS, which provides cfengine 3.2.4 via apt-get.

Local Use Only

The most simple use is with only a single computer and no distributed stuff or networking. This is a little bit like using git for one-file scripts.

Cfengine insists to keep everything in its own directory. However, Debian has somewhat patched it to confirm a little bit more to Unix conventions. Most importantly, you care about the files in /var/lib/cfengine3/inputs/, especially promises.cf. Write all your configuration stuff in there for now. Here is a simple file:

body common control {
  bundlesequence => { "selfexec", "packages" };
  inputs => { "cfengine_stdlib.cf" };
}

bundle agent selfexec {
files:
  "/etc/cron.hourly/cfengine3"
    copy_from => no_backup_cp("$(sys.workdir)/inputs/cronscript.sh"),
  perms => mog("755", "root", "root");
}

bundle agent packages {
vars:
  "ubuntu_packages" slist => {
    "cfengine3",
    "bash",
  };
packages:
  ubuntu::
    "$(ubuntu_packages)"
      package_method => apt,
      package_policy => "add",
      action => if_elapsed(1440);
}

The first block body common control is kind of the main function. It specifies to import the standard library cfengine_stdlib.cf and to evaluate the two bundles "selfexec" and "packages". Bundles are like modules or packages in programming. It allows you to split your stuff into reasonable chunks. You have to copy /usr/share/doc/cfengine3/example_config/cfengine_stdlib.cf next to your promises.cf or you get an error message.

The second block selfexec moves a script from the inputs directory into /etc/cron.hourly/cfengine3. This script ensures that this configuration is reinforced every hour.

The third block packages ensures that two packages (cfengine3 and bash) are installed via apt. However, this is only done every 1440 minutes, so once per day. The main reason for this delay is that cfengine implicitly does apt-get update on each run.

So far, this configuration was not applied. Simply run sudo cf-agent -v. Of course, you can omit that -v, but it gives you a glimpse what cfengine does and why. By the way, this all cronscript.sh does. From now on, cron (more precisely anacron on Ubuntu) and cfengine will keep your system as promised in your configuration.

The next steps would be to use the server-client machinery for our single host. Afterwards add more hosts.

© 2015-10-25