July 28, 2010

Chef cookbook attribute files

Learned today the hard way: Don't use set_unless in a Chef cookbook's attribute file unless there is a really good reason. And corollary: there's never a really good reason. At least, not that I've found.

Why? Here's what happened. I started hacking Chef recipes by looking at examples from the Opscode and 37Signals git repos, probably like many folks. In many of those examples, attributes are set using things like

set_unless[:cookbook][:varname] = "some_value"

The problem is that what set_unless means here is that whenever this cookbook is run, Chef checks to see if the variable in question already has a value...any value. If so, it skips the set statement. See where I'm going?

Yeah. So I had an attribute with a really long list in it that was going to be executed by a stanza in my main recipe file. To test it, I created a three-item list in the attribute file. It worked fine on my test node. So I changed the attribute to have the full 21-item list, and then re-upped the cookbook to the Chef server, and re-ran the client on the node. It diligently went and got the updated attribute file and downloaded it to the cache, then performed the chef run...with the same 3-item list.

Because I'd already set that variable on that node, the set_unless wouldn't fire. The only way I got this to work was to go replace the set_unless statements with plain ol' set statements. Then, when it ran, it happily overwrote all the variables with the new values.

Does this waste time/resources? Yes, but probably not as much as a set_unless_equals sort of test would (not that that test exists now).

Posted by jbz at July 28, 2010 6:58 PM | TrackBack

Post a comment

Remember personal info?