Chef has been announced. Listen to this podcast at Cloud Cafe. There’s no way around comparing puppet and chef. Sure, they’re both configuration management tools. It’s simplest to put it this way:
We’re replacing puppet with chef.
And why? A little while ago I wrote about problems I’ve been having scaling puppet. Off the top of my head, the biggest issues for me working with puppet have been:
- Dependencies graphs
- Limited capabilities of the language (DSL)
- Templates are evaluated on the server
Dependency Graphs
There’s a talk about vertically scaling puppet, but not a lot of it about horizontally scaling. I tend to run everything under puppet. People argue that it’s too much work to put single servers in puppet, and you should only use it for systems you intend to clone. I disagree. Puppet recipe’s are self documenting. The same people who don’t want to take the time to write puppet recipes for the single services are the people you have to beat with a sucker rod to get to document anything. Sometimes if I don’t have the time to put into fully testing a puppet recipe for a new machine, I’ll at least write the recipe as I’m working to server both as documentation and a starting point for if/when I come back to it.
The point is that as I scale out in this fashion, more often puppet will fail with a dependency problem on one run, and be fine on the next. I asked Luke about this at a BoF at OSCON 2008, and he basically told me that he really only focuses on the problems his paid customers have and was anxious to leave and get a beer. That’s fine, I understand it, but since it does nothing to fix my problem it drove me away from the puppet community.
While in theory having puppet do all this work to resolve depency issues seems fine, it is more complexity and trouble than it is worth. As a systems administrator I know what the dependancies are. As you build a system you simply write your recipe in the same order as the steps you’re taking.
Chef takes this idea and runs with it. Recipes are parsed top to bottom. If a package needs to be installed before a service is started, you simply put the package in the recipe first. This not only makes a lot of sense, it makes depencies in a complex recipe visually understandable. With puppet you can end up with spaghetti code remincisent of “goto”, jumping around a number of recipes in an order that’s difficult to understand.
Language
Before the recent 0.24.6, you could not even do:
if $ram > 1024 { $maxclient = 500 }
The support for conditionals was rudimentary. I run into a lot of languages and the biggest problem I have is remembering how to do the same thing in each language. The puppet language does not do what a lot of lot of other languages do. I didn’t need another language to learn, let alone one written from scratch. It was just silly doing something like:
# iclassify script addes vmware-guest tag based on facter facts $is_vmware = tagged('vmware-guest') if $is_vmware { include vmware }
Chef uses ruby for it’s recipes. This makes the above stupidly simple with something like:
include_recipe "vmware" if node[:manufacturer] =~ /VMware/
Templates
Puppet evaluates recipes and templates on the server. I ended up with this block of code once when I need to specify the client node’s IP Address in a configuration file:
require '/srv/icagent/lib/iclassify' ic = IClassify::Client.new("https://iclassify", iclassify_user, iclassify_password) query = [ "hostname:", hostname].to_s mip = nil nodes = ic.search(query) nodes.each do |node| # node.attribs is an array of hashes. keys is 'name' value is 'values' node.attribs.each do |attrib| if attrib[:name].match(/ipaddress/) ip = attrib[:values].to_s if ip.match(/10.0.0./) mip = ip break elsif ip.match(/10.0.1./) mip = ip break end end end end
This was so much work. Of course with chef you can easily get this information in the recipe because it’s parsed on the node, let alone the ease of doing it in the template if that’s more appropriate. Since the template’s parsed on the client, you grab the information out of variables or directly from the system.
As time goes on I’ll surely write more about using chef. We’re using it production now, and happy with it. In the interim, come to #chef on freenode if you have any questions.