Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get current recipe attribute file to be loaded first?

Tags:

chef-infra

I have recipes and attribute files for nodes. E.g. localhost and linode. I am trying to get the attribute file to load first (and to set hostname etc) before the default or other attributes. Example:

attributes/localhost.rb:

default[:hostname] = "localhost"
default[:nginx][:hostname] = 'mbdev-localhost'

include_attribute 'mbdev::common'

attributes/common.rb

default[:nginx][:website1][:url] = "subdomain." + default[:nginx][:hostname]

recipes/localhost.rb

include_recipe 'mbdev::default'

runlist:

'mbdev::localhost'

However it seems include_attribute makes the 'common' attribute to load first. And so nginx-hostname is not yet set...

The order I get is: 1) Loading attributes/default.rb 2) Loading attributes/common.rb 3) Error about the +

How can I get localhost.rb to load before common.rb?

like image 935
mbdev Avatar asked Oct 28 '13 06:10

mbdev


2 Answers

By default, attribute files are loaded in alphabetical order. This used to be not fully consistent everywhere but was fixed in CHEF-2903.

Thus, your attributes/common.rb is loaded before attributes/localhost.rb simply because it comes earlier alphabetically. An exception from the rule is attributes/default.rb which is always loaded before any other attributes files in a cookbook.

Generally, the load order of attribute files is the following:

  1. load the attributes of all cookbook dependencies in alphabetical order
  2. load attributes/default.rb (is it exists)
  3. load any other attributes files in alphabetical order by filename

You can load an attribute file earlier than it would normally be loaded by using include_attribute, but you can't make it load later that way.

This logic is hardcoded in chef and can't be changed. You can perform a few work-around though:

  • You could write your attribute files in a way that load order is not important anymore
  • You could name recipes/attributes in a way consistent with the above logic
  • You can enforce that an attribute file is loaded again:

    node.from_file(run_context.resolve_attribute("cookcook_name", "attribute_file"))
    
like image 53
Holger Just Avatar answered Nov 09 '22 11:11

Holger Just


Why not using override_attribute? That's why they exist :-) See Attribute Precedence.

like image 22
StephenKing Avatar answered Nov 09 '22 11:11

StephenKing