I always thought that one of the most rewarding effect of Puppet is that the whole system gets configured automatically as nodes are added. For me, the main, and for a long time sole, manifestation of this property is in the configuration of the Nagios servers. The built-in types lend themselves pretty well to this exercice.
Now, with PuppetDB, we have a simple and powerful way to create new effects, beyond what could be achieved with just exported resources (I believe it used to be possible before PuppetDB, but required black magic in the template files). I will demonstrate a typical use case, along with a sneak peak of the testing features that will appear in the next version of language-puppet.
Let’s say we have an HTTP proxy and several groups of servers acting as backends. You wish to be able to add servers to the pool just by running the agent on them. The
site.pp should look like this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
haproxy::backend defines are empty, and the interesting part is in the
1 2 3 4 5 6 7 8 9 10 11
pdbresourcequery function comes from this excellent module, and has been included natively in language-puppet for a while. Its effect here is to fill the
$backends variable with an array containing all resources that are of type
Haproxy::Backend on any active node.
But now comes the complicated part: how are you supposed to write, and, more importantly, to test, the
config.erb template ? As far as I know you can’t pull this off with
puppet-rspec (and it is way too slow anyway). With the new testing API, you can write a simple program like this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
Line by line, this program does:
- lines 1-10 : various headers
- line 11 : the catalog computing function is initialized, using the new testing system
- line 12 : the catalog for the node
back1is computed, and stored into the fake PuppetDB
- line 13 : same thing for
- line 14 : same thing for
proxy, but we keep the final catalog this time
- lines 15-19 : the content of the
/etc/haproxy/haproxy.cfgis displayed. This part is terrible and will be replaced by some helper soon.
The template groups the resources by their “backend_type” attribute, creates a backend block for each of them, and populates the blocks with the corresponding backends.
1 2 3 4 5 6 7
And the output is :
1 2 3
It works! With this feature, it will soon be possible to test and experiment with the most complex aspects of inter-node interactions.