I\'m using the opscode nginx cookbook for configuring the nginx server on my nodes. The nginx cookbook has some default attributes I\'d like to override in my role (\"web_se
This question is from 2012 and is very, very old. The first suggestion I have is to be more explicit around creating the hash argument, and the precedence level should be set to default, never override:
name "web_server"
description "Setup a web server"
run_list "role[base]", "recipe[nginx]"
default_attributes({
'nginx' => {
'install_method' => "source",
'version' => "1.2.3",
'source' => { "prefix" => "/opt/nginx", "checksum" => nil }
}
})
The problem is likely related to Derived Attributes that were being used in the nginx cookbook:
default['nginx']['version'] = "1.2.2" # in cookbooks/nginx/attributes/default.rb
default['nginx']['source']['prefix'] = "/opt/nginx-#{node['nginx']['version']}" # in cookbooks/nginx/attributes/source.rb
If a higher-level override is not set by previously parsed configuration at the time that the second line is parsed it will immediately pick up the first line. Since at least Chef 11 role attributes always win over default attributes in attributes files. Even back in Chef 10 override role attributes should have been already parsed and should beat the default set in the first line here. I do not know why the override attribute was not working for this user back in 2012. This may have been related to simple bugginess in Chef 11.x versions around generating the merged view of all the precedence levels (bugs long since fixed, but I cannot recall the details any more).
I would encourage anyone currently reading this question to use PolicyFiles, which replaces roles, environments and Berkshelf files. All of the latter are still supported but no further development is going into them.
Have you tried with parentheses? I tried your example with parentheses and got the default attributes overridden.
# your roles/web_server.rb file
override_attributes(
'nginx' => {
'install_method' => "source",
'version' => "1.2.3",
'source' => { "prefix" => "/opt/nginx", "checksum" => nil }
}
)
You can also use override attributes in role editor (in web or knife role edit)
{
"name": "web_server",
"description": "nginx version",
"json_class": "Chef::Role",
"default_attributes": {
},
"override_attributes": {
"nginx": {
"version": "1.2.2"
}
},
"chef_type": "role",
"run_list": [
"recipe[]",
"recipe[]"
],
"env_run_lists": {
}
}
According to the Chef Attribute Preference document, this should work:
name "web_server"
description "Setup a web server"
run_list "role[base]", "recipe[nginx]"
default_attributes 'nginx' => {
'install_method' => "source",
'version' => "1.2.3",
'source' => { "prefix" => "/opt/nginx", "checksum" => nil }
}
You shouldn’t use override_attributes
in roles. Once you start using overrides instead of defaults, you’ll quickly end up finding you’ve used the strongest possible override and have no further way to override it. Use default_overrides
instead.
The precedence rules around attributes, using only the default
level are actually pretty same:
require_two_factor_auth
is forced to true with default_overrides
in role[single_sign_on]
, even in QArequire_two_factor_auth
is forced to true in production
require_two_factor_auth
is set to true in auth::two_factor
require_two_factor_auth = false
However, it’s extremely unusual for the same attribute to be set in all four of those places, though. If the correct value of the attribute really depends on the recipe and the role and and the environment, then usually the resulting value combines features of all three, and a different attribute is set at each level and combined in the recipe.
If this isn’t working, two possibilities are:
chef-client -o "recipe[nginx]"
instead of chef-client -o role[web_server]
or plain chef-client
If that’s not the case, please provide more detail. I use this all the time and it’s always worked, and I’d be concerned if there were edge cases where this does not behave as documented.
The only problem I could guess is that these attributes must have been over-ridden by force_overridden attribute. Also ensure that the attributes you have over-ridden are available for the runlist(since I'm skeptical about the way you have arranged your role file)
The attribute precedence chart [1] shows that these four options rank above your role:
12. An override attribute located in an environment
13. A force_override attribute located in a cookbook attribute file
14. A force_override attribute located in a recipe
15. An automatic attribute identified by Ohai at the start of the chef-client run
If these don't appear to be the cause, then perhaps changing your formatting might help. I would write it like:
override_attributes(
nginx: {
install_method: 'source',
version: '1.2.3',
source: {
prefix: '/opt/nginx',
checksum: [ ],
},
}
)
[1] https://docs.chef.io/attributes.html#attribute-precedence