Finally, we are ready for the CFEngine 3.2.0 release and we’ll have a look at the major changes. In 3.2.0, an exciting CFEngine Nova feature is brought into the community edition, and a set of out-of-the-box policies are released to standardise and simplify CFEngine installations. This will make bootstrapping new CFEngine’d hosts a breeze. Also, as usual, a bunch of new features and bug fixes also made it into the release.
We will cover the following items this time.
- The brand new
- More convenient use of ifvarclass
- Package-promises improvements
- Editors to support the CFEngine language
If you look at
cf-agent --help, you will notice that a new option,
--boostrap (-B), has been added to the community edition. Also note the
--policy-server (-s) option – they go hand-in-hand. These options, when combined, allows you to specify the IP address of a policy server on the command line. The IP address will then be used when the bootstrapped node pulls for policy updates. So this is easier than the conventional way to put a new node under management; manually deploying a custom policy and running
So say we have a policy server running at 192.168.1.1. On a fresh client, we run
/var/cfengine/bin/cf-agent -Bs 192.168.1.1. Let’s break
cf-agent‘s actions down into a series of steps, to see what is actually happening.
- Write the address from the
--policy-server (-s)option to
- Check if
/var/cfengine/inputs/failsafe.cfexists, run it and exit if it does
- Write an embedded failsafe policy to
/var/cfengine/inputs/failsafe.cf(we’ll explore this in a moment)
- Run the embedded failsafe policy
- The embedded failsafe pulls down a new policy from
- Bootstrapping is now finished and the new node is under CFEngine management!
This means that all you need to have is a policy server sharing a policy under
/var/cfengine/masterfiles and then run one command at the clients to put them under management!
So how does this embedded policy look? It is actually a very simple policy mainly consisting of a file-copy promise and a promise to start
cf-execd. You can actually see the embedded failsafe as failsafe.cf.cfsaved after a host has been successfully bootstrapped.
Since it is embedded in the CFEngine binaries, it is not very pretty with respect to indentation and Knowledge Management features, but it does the job. For your convenience and curiosity needs, I have uploaded the CFEngine embedded failsafe.cf. Also note that it cannot be changed since it is embedded (and this is why it is so simple), but the policy that gets pulled down is of course entirely up to you.
Bootstrapping the policy server
Until now, we have assumed that the policy server is already set up for us in advance. But, as a matter of fact, bootstrapping the policy server is almost exactly as easy. It will just use its own IP address, thus all hosts will use the exact same bootstrap command. However,
/var/cfengine/masterfiles should be populated with the desired policy before bootstrapping it (otherwise, it has no policy to grab!). But CFEngine 3.2.0 also gives you a head start with the bundled policy.
The bundled policy
So what do you put in
/var/cfengine/masterfiles on the policy server prior to doing any bootstrapping? In order to get policy updates, it should contain a promise to check for updates from the policy server, and the policy server needs to grant access to the directory with the policy updates (
/var/cfengine/masterfiles by convention). But there are also a few other items users always want, like a
promises.cf policy with the
inputs. Also, you might want to configure
cf-execd‘s email functionality. And then there’s the
cf-serverd access configuraion..
CFEngine 3.2.0 is distributed with a skeleton policy that allows to change these normal parameters without needing to write your own version of everything — just plug in the data in the right place. If grab a tarball, you will find the bundled policy in the masterfiles subdirectory after you unpack it. Otherwise, you can always get it from the CFEngine core subversion repository.
Before starting using it, you can look through
promises.cf to adjust it to your needs. In particular, have a look at the
bundle common def. The
acl slist there determines the access rules for
What about trust?
As we know, simplicity and security are often conflicting. In order to make our easy bootstrapping work, two kinds of trust are assumed.
- Bootstrapping host trusts the policy server’s public key and the policy it holds
- Policy server trust the new client’s public key and gives access to the policy
The first item is implicit from running the bootstrap command. We are essentially asking the client go to the given IP address for policy updates. If we do not want to assume this kind of trust for some reason, we have to revert to the old way of copying the policy and/or the policy-server’s public key manually. An automatic bootstrap procedure will not be useful to us in this case.
However, we can do something with the second item. First off, we can allow only certain time windows of client trust in the server. We can also limit the (ranges of) IP-addresses we accept. By default we allow the Class B network to access the policy server. See the
acl slist in
bundle common def in
promises.cf to configure it.
Improvements for ifvarclass
As you perhaps know, ifvarclass can be used to transform a variable into a class expression. With CFEngine 3.2.0 you can also make convenient expressions and tests directly in the ifvarclass expression using the new special functions and(), not(), or() and concat(). This can save you class definitions that you would use only once.
For example, you might want to copy down some configuration only to hosts having a certain binary. This can now be done easily with one promise, as shown below.
copy_from => remote_cp(“/var/cfengine/sitefiles/etc/testservice”, “22.214.171.124”),
ifvarclass => or( fileexists(“/bin/testservice”) );
Also note that you can wrap any number of function calls, as shown by the dummy-example below.
“/tmp does exist”
ifvarclass => not( not(fileexists(“/tmp”)));
If you would like to test the two examples on your own, you can download them here.
A pack of bugfixes
As usual, the CFEngine developers have been working hard to check and fix bugs reported by the community. In particular, the
packages-promises have gotten a facelift.
addupdate package policy is now fully functioning when using a repository-enabled manager such as
aptitude. Previously this policy was only supported when specifying package_file_repositories combined with non-repository package commands such as
dpkg. For example, the following promise will make sure Apache is installed with a version at least 2.2. If Apache 2.2 or newer is already installed, no action is taken.
package_method => generic,
package_version => “2.2.00”,
package_select => “>=”,
package_policy => “addupdate”;
Also, for efficiency reasons, CFEngine caches the list of installed packages and their version (the output from package_list_command) in
WORKDIR/state/software_packages.csv. A problem encountered by some users was that CFEngine did not actually update this cache often enough, so CFEngine might actually act on stale information. To alleviate this problem, package cache invalidation is introduced in this release. Also note that you can define the cache maximum age with the package_list_update_ifelapsed attribute. There were also a few other package-related issues that were addressed in the 3.2.0 release.
For a complete list of the reported issues/feature requests that was resolved in CFEngine 3.2.0, have a look at the Change Log at the bug tracker.
Lastly, some very good news for Emacs users! Ted Zlatanov, an active member of the CFEngine Community, has created and committed cfengine3-mode to Emacs sources. This has also been added to contrib in the CFEngine core repository.
If you are a vim-er, don’t despair! Have a look at the vim syntax highlighting script and the abbreviations and help files. Both are contributed by Neil Watson, also an important member of the CFEngine community.
As usual, CFEngine 3.2.0 is provided not only as a source tarball, but also prepackaged for the most popular Linux distributions by logging into the Engine Room (free registration required). Users of the following distributions enjoy free packages, both 32- and 64-bit versions.
- Debian 5 and 6
- Fedora 14 and 15
- Red Hat Enterprise Linux 4, 5 and 6
- Suse 9, 10 and 11
- Ubuntu 8, 9, 10 and 11
Note that most distributions also maintain a CFEngine 3 package, but this is usually older and may not be built in a uniform way.
Please do not hesitate to leave a comment if you found this useful, have suggestions for improvements, or would like to see other CFEngine-related get covered.
Go get those hosts CFEngined!