popularity question answers views user  
2
Overriding attributes referenced by other attributes

I am having trouble understanding the proper way to define my recipe’s attributes and allow for certain ones to be overridden in roles. The classic example is where you have one attribute for the version of an external library and then another attribute that constructs a URL which references the first version attribute. Then, if the version number is overridden, the URL gets updated as well.
The problem is, setting an attribute in a role does not seem to affect other attributes that reference the changed attribute.

Example:

attributes/default.rb

default['noodle']['foo'] = "foo-version-1"
default['noodle']['bar'] = "bar-version-1"
default['noodle']['baz'] = "#{noodle['foo']} & #{noodle['bar']}"

recipes/default.rb

Chef::Log.info "NOODLE: Value for foo = #{node['noodle']['foo']}"
Chef::Log.info "NOODLE: Value for bar = #{node['noodle']['bar']}"
Chef::Log.info "NOODLE: Value for baz = #{node['noodle']['baz']}"

roles/noodle.rb

name 'noodle'
run_list(
  'recipe[noodle]'
)
default_attributes({
    :noodle => {
      :bar => 'bar-version-2'
    }
  })

chef-client run output

INFO: NOODLE: Value for foo = foo-version-1
INFO: NOODLE: Value for bar = bar-version-2
INFO: NOODLE: Value for baz = foo-version-1 & bar-version-1

Using ‘override_attributes’ instead of ‘default_attributes’ doesn’t make a difference:

name 'noodle'
run_list(
  'recipe[noodle]'
)
override_attributes({
    :noodle => {
      :bar => 'bar-version-2'
    }
  })

chef-client run output

INFO: NOODLE: Value for foo = foo-version-1
INFO: NOODLE: Value for bar = bar-version-2
INFO: NOODLE: Value for baz = foo-version-1 & bar-version-1

I have discovered that if I literally set one of those attributes on the node, it gets picked up.

Set node attribute with ‘knife node edit NODE’:

{
  ...
  "normal": {
    "noodle": {
      "foo": "foo-version-NODE"
    }
  },
  "run_list": [
    "role[noodle]"
  ]
}

Then a chef-client run shows:

INFO: NOODLE: Value for foo = foo-version-NODE
INFO: NOODLE: Value for bar = bar-version-2
INFO: NOODLE: Value for baz = foo-version-NODE & bar-version-1

Isn’t this what roles are for? I need to be able to manage attributes like this en masse and in source control (role files). There are several official cookbooks that are designed the same way such as java, couchdb, and munin so it seems like it should be supported somehow.

more →
1 1.3k