A blog

Cookbook Reusability In Practice

I recently attempted to use Chef to configure several VMs with software I wanted to play with. My goal only went as far as provisioning a minimally useful instance of each application – it didn’t need to be production-ready, but it did need to start.

The applications were:

  • Jenkins, a CI tool written in Java,
  • Graphite, graphing tool written in Python, and,
  • Sensu, a monitoring tool written in Ruby.

Additionally, Sensu requires:

  • RabbitMQ, a message broker written in Erlang, and,
  • Redis, a key-value store written in C.

None of the dependencies are particular esoteric in a modern environment, though the variety seen here underscores the need for good configuration management. The guest OS was Ubuntu 12.04, as many community-contributed Chef cookbooks prefer or require Ubuntu and I wanted things to proceed as smoothly as possible.



My experience installing Jenkins was not without issues, but it came closest to meeting my expectations. Adding recipe[jenkins] to the run_list will also pull in recipe[java::default], which will install openjdk unless configured otherwise using node attributes. I used the defaults.

The first chef-client run failed with the following unhelpful error in the Java cookbook:

[Sat, 09 Jun 2012 17:27:41 +0000] ERROR: TypeError: ruby_block[update-java-alternatives] (java::openjdk line 43) had an error: TypeError: can't convert nil into String

Without fixing or changing anything, I ran chef-client again – this second time, it completed without error, leaving Jenkins available on port 8080.


For the next VM, I added recipe[graphite] to my run_list without overriding any attributes – the README suggested that an override was required on Ubuntu 11.10, but I decided to try my luck with the defaults on 12.04.

The graphite cookbook pulls in recipe[python::default], which is currently broken on Chef 0.10.10 and later. I had to patch my local copy of the cookbook (see this pull request for the fix) before re-running chef-client.

The second run completed without error, leaving Graphite running on port 80. But for the bug in the Python cookbook, this would have worked on the first go, without any manual tweaks.


Bringing up a VM to try out Sensu was a yak shaving saga. The Sensu cookbook tries to make the process easy by shipping example roles, which show how to install and configure the tool in various ways. To simply install of the dependencies (Redis and RabbitMQ), recipes are provided which wrap their respective cookbooks, configuring the software for use by Sensu.

The cookbook’s docs specify where to get each of its cookbook dependencies from, and even includes a Cheffile (for use with librarian-chef) that will take care of it for you. I downloaded the dependencies by hand, and got the wrong version of the Redis cookbook in the process.

That’s how I learned that the Redis cookbook on the community site depends on metachef, which only works on Ruby 1.9 and is therefore off limits to most people running Chef on the Ruby shipped with their OS. That’s pretty weak. (The redis cookbook referred to by the documentation does not depend on metachef)

After that, I was blocked installing RabbitMQ as their website was down, and stayed down for most of the four-day weekend the UK had for the Queen’s Silver Jubilee.

Eventually, everything installed successfully and Sensu started, but didn’t appear to work as intended. I’m still working on this, and have yet to determine whether it’s an error on my part.

Credit Where Due

Despite the problems described above, I want to sincerely thank everyone who shared the code and cookbooks I’m using. It sounds ungrateful to complain when things don’t quite work, given just how much did work. I’m bothered by this state of affairs, because I know I’m not immune to it – the cookbooks I share work for me, but I’d like them to work for everyone else. I doubt they do, and I have no way of knowing.

Re-use in the large is a hard problem, and one that we need to solve as a community. We have not yet done so. Until we do, individual cookbook authors can only do so much.

A possible future

The perl community does a lot of work to support code re-use via CPAN, the Comprehensive Perl Archive Network. CPAN is more than a package index – mirrors and testers are key features.

Like Chef, perl runs on many platforms, and many different releases can be found in the wild. When something goes wrong, it’s valuable to know whether it’s only going wrong for you, or whether a given module is known not to work on your class of system.

CPAN Testers collates results of tests for every module across a broad set of platforms and perl versions. Here are two examples for DBD::Pg:

As a user, I can quickly find out whether a module is likely to work on my system. As a module author, I get rapid feedback when I screw something up for a user on a platform I don’t test on myself.

We have little hope of promoting widespread use of shared cookbooks until we can show that the work we share functions correctly across the set of platforms we intend to support – and continues to do so as both platforms and cookbooks evolve.