Chef: Attribute Overrides in Recipes Is a Bad Idea
I like Chef, but some aspects of its internal kitchenary are pretty poorly documented (or I’m not good enough with Chef to understand why it should behave this exact way).
I’ve hit an annoying problem trying to fix library in a chef cookbook:
I had an attribute assigned in attribute file vault-cookbook/attributes/default.rb:
...
default['vault_name'] = 'foo'
...
and override in recipe vault-cookbook/recipes/some_recipe.rb:
...
override['vault_name'] = 'bar'
...
search_node() function is called from some_recipe.rb and described in a library vault-cookbook/libraries/library.rb:
class Chef
class Recipe
def search_node(vault_name=node['vault_name'])
nodes_in_all_vaults = search(:node, 'recipes:vault-cookbook\:\:vault-member')
Chef::Log.info "Node #{node['fqdn']} is in vault #{node['vault_name']}"
nodes_in_all_vaults.each do | node_object |
Chef::Log.info "Node #{node_object['fqdn']} is in vault #{node_object['vault_name']}"
# some yadda-yadda code
end
end
end
end
search_node() function gets vault name and performs some actions with nodes in this vault.
###Now the magic
Guess if two log resource calls in library return same results for same node. Hell no!
Chef::Log.info "Node #{node['fqdn']} is in vault #{node['vault_name']}"
returns
Node node.fqdn.com is in vault bar
this is ok, override works. But
Chef::Log.info "Node #{node_object['fqdn']} is in vault #{node_object['vault_name']}"
returns
Node node.fqdn.com is in vault foo
override does not work because override from the recipe is not being applied to node objects found during search, they have vanilla set of attributes.
So if you want to avoid pitfalls keep your attributes in attribute files/roles/environments, not in recipes.
Just to be clear, mentioned issue appies to Chef 11, didn’t test on other versions.