Confused with naming attributes

Hello community!

Please help with naming rules chef’s attributes. I have read that attributes have 6 types attributes and they may set up from up to 5 locations what in result give 15 different values. https://docs.chef.io/attributes.html#attribute-types

Types are: default, force_default, normal, override, force_override, automatic. Ok.
And locations from which they may come in are: Nodes, Attribute files, Recipes, Environments, Roles.

I confused how in name attribute these values should be reflected and SHOULD?
Can i name attribute just [my_attribute] or i need specify type default[my_attribute] or if i not specify type some of types will be set by default?
Or i should specify location in name of attribute from where it come? Like: recipe[my_attribute]?

Also i see in documentation attribute: node['platform'] node not belong to types nor locations?

In generally which name should be passed before sq. brackets [] in attribute name? I thought it should be type like default, normal, etc. But node confused me it is not type nor source.

Thank you!

Hi @mpolitaev,

The type refer to attribute precedence. It is basically about which attribute declaration wins on the same attribute. The locations are the different places where attribute declaration can happen. There is a table that provides a good summary about these two topics(the highest number wins from a precedence point of view):
https://docs.chef.io/attributes.html#attribute-precedence

From the attributes that you create (and from other sources like ohai) the node object gets created. In recipes you can refer to the attribute through the node object: node['my_cookbook']['my_attribute']

The following patterns should be followed:

  • try to use default type only
  • if your cokbook’s name is my_cookbook then your cookbooks’s attributes should be under that namespace default['my_cookbook']['my_attribute']

Some further readings:
https://coderanger.net/two-pass/
https://docs.chef.io/ohai.html
https://docs.chef.io/nodes.html#node-objects

Simark, thank you for explanation.

I know about attribute precedence. I have read. But my question is another.

default['my_cookbook']['my_attribute'] – why there default at begin? Because it refer to attr. type. Right?

node['my_cookbook']['my_attribute'] – why node at begin? I dont read about that type. Only default, force-default, normal, override, force-override and automatic.

Assume there node is object and:
default['my_cookbook']['my_attribute'] the same as
node.default['my_cookbook']['my_attribute'] ?

Then what mean:
node['my_cookbook']['my_attribute'] without node? Which type? Is there some default type will be used in?
['my_cookbook']['my_attribute']

In my previous comment I have said that the node['my_cookbook']['my_attribute'] syntax is used when you want to refer to the attribute in a recipe. Since you can declare attributes in recipes, but through the node object, you have to use a different syntax: node.default['my_cookbook']['my_attribute']
The ['my_cookbook']['my_attribute'] is causing syntax error. You must specify a type when declaring an attribute and when you refer to an attribute you have call the node object

More clear now.
So when i refer to attribute i can’t refer to specific type like default and should use only:
node['my_cookbook']['my_attribute']

But if i want to declare some attribute i should specify type like:
node.default['my_cookbook']['my_attribute'] or
node.force-default['my_cookbook']['my_attribute']
That is?

  • in attributes: default['my_cookbook']['my_attribute']
  • in recipes node.default['my_cookbook']['my_attribute']

The point of the attribute precedence system is to allow you (or an upstream cookbook author) to set sensible defaults for data that the end-user can override as needed. For example, a generic cookbook for a web server might configure the server listen on port 8000 so it doesn't need root, but you could set it to port 80 for a production scenario.

Whenever you set a value for an attribute, you are required to do something to specify the precedence level you want to write to, because Chef can't guess this on your behalf. 99% of the time, when you read the value, you want the highest precedence one.

So:

Basically yes. You can read from specific values but there's almost never a reason you'd want to.

There's a wrinkle here that, in an attributes file, the node part is implicit (you can still use it if you want, but it's not idiomatic). In a recipe, the syntax you've given is correct. But note that mostly you want to set default level values. Also, Ruby doesn't allow hyphens in method names, the correct name is force_default.

Ok, thank you.

If i declare before:

node.default[‘my_cookbook’][‘my_attribute’] = 123
node.force_default[‘my_cookbook’][‘my_attribute’] = 456

And then refer in recipe to:
node[‘my_cookbook’][‘my_attribute’] should it return by precedence rules 456?

But if

node.default[‘my_cookbook’][‘my_attribute’] should be 123 still?

Am i right?