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 6:58 PM | Comments (0) | TrackBack

July 12, 2010

Amazon EC2 ami manifests and architecture mismatches

So I'm muddling my way through various means of managing an AWS infrastructure. We're currently using Opscode's chef and their online SaaS implementation (experimentally). When using the chef tool 'knife' to boot up an EC2 server using one of our custom AMIs, I kept getting an error:

---cut---

/usr/local/lib/ruby/gems/1.8/gems/excon-0.1.4/lib/excon/connection.rb:67:in 
`request': InvalidParameterValue => The requested instance type's architecture
(i386) does not match the architecture in the manifest for ami-xxxxxxxx (x86_64)
(Fog::AWS::EC2::Error)

---cut---

...after mucking about for a bit, I have discovered that AMIs whose declared arch is x86_64 (and, presumably, whose arch2 is amd64) *cannot* be used to instantiate running instances whose type are m1.small or m1.large. This matters because while some DSL tools (*cough* chef *cough) have the means to specify and pass thru an instance 'flavor' to the EC2 toolset, they can't/don't/won't accept or pass thru an 'arch' value. So the error message is a bit of a red herring. In my case above, I changed the instantiation command from specifying '-f m1.large' to '-f m1.xlarge' and...voila, it worked.

Posted by jbz at 2:23 PM | Comments (0) | TrackBack