Opscode Chef and the Single Responsibility Principle

My current project is managing the software and distribution of a hardware appliance. We send out physical machines to our customers and we really need to know that they are all identical.
I’ve set up a build system that uses PXE to boot the Ubuntu installer, which is preseeded with a very basic install of linux. We then use chef (actually chef-solo) to configure the remainder of the software. (I’ll write a bit more about the reasons behind this later)

While I’ve been writing new recipes, I’ve started using a pattern that ensures good separation of responsibilities while making the recipes themselves easy to read.

In my pattern, the default.rb file in the recipe consists only of includes. The default recipe is used to make sure that something useful happens.
For example, I created a recipe to install and configure the Hamachi VPN client. This consists of two recipes; install.rb (which downloads and installs the appropriate package and dependencies) and connect.rb (which authenticates with Hamachi and joins the appropriate network). The default.rb includes these two recipes.

I’ve found that this style results in much tidier recipes.