Attributes are Node data such as the IP address, hostname, loaded kernel modules, version of programming languages available on the system and more. New attributes can be dynamically added to the node in a variety of ways.
During the Chef run, the Chef Client saves these node attributes on the Chef Server where they are indexed for Search. When the Chef Client runs again, it will retrieve the attributes that were saved previously and merge in attributes based on the priority rules described below.
Attribute Type and Precedence
There are three types of attributes in order of precedence, highest to lowest.
Write your cookbooks with default attributes, but override these with role-specific or node-specific values as necessary.
A fourth attribute type,
Attributes are a special key-value store called a Mash within the Ruby DSL context. A Mash is just a Hash where the key can be either a Ruby symbol (:key) or a string ("key"). The keys are also auto-vivified into accessor methods, which we'll talk about in a moment.
Attributes may be set on the node from the following objects
The precedence of the attributes is as follows, from low to high:
See examples here...
Cookbook attribute files are found in the
e.g. from Opscode's Apache cookbook:
The use of the node object is implicit here. The following is equivalent:
Attributes can be set in a recipe as well, but
Cookbook Attribute Methods
Use the following methods within a cookbook's attributes file or in a recipe. They correspond to the attribute type of the same name (set is an alias for normal).
Additionally, there are
Another handy method available related to attributes is the
In the recipe, we need to use the method on the node object. In the attributes file, the node object is implicit. In either, we can also look for a sub-key of an attribute by chaining the attribute as methods:
Cookbook Attribute File Ordering
When Chef loads cookbook attribute files, it does so in alphabetical order for all the cookbooks. If you need to ensure that one attribute file is loaded before another (for example, if your Rails cookbook requires that the Apache attributes are available first) you can use the
The syntax for this follows the same "double colon" pattern as
This loads the
Reloading Attribute Files From Recipes
Attributes sometimes depend on actions taken from within recipes, so it may be necessary to reload a given attribute from within a recipe. For example: if you have an attribute that reads firewall rules, and a recipe that installs a firewall package, the firewall attributes will not be set the first time you execute the cookbook. Since
Attribute Accessor Methods
Attribute accessor methods are automatically created and the method invocation can be used interchangeably with the keys. The following is equivalent to the usage above:
This is a matter of style, and may be seen when "retrieving" the value of an attribute.
Environments can set attributes, which is a kind of
Roles can only set
Finally, the node object can be modified directly to set the attributes. Typically, this sets attributes at the
You can also specify node attributes with a JSON file. These are applied at the
For example, to set up some different ports for Apache to listen on:
Remember, that attributes passed via JSON file are merged with those stored on node and actually there is no way to override them in that way, however if there is a conflict, attributes from JSON file will win with those stored on node.
How to Use Attributes
Good candidates for Attributes are:
Usage Best Practices
The general pattern for attributes precedence is that cookbooks and roles should be setting defaults. If you need to change the values for a specific node, use, the normal attributes on the node. Overrides are there so roles can force a certain value even if the node already has a value there. There are certainly other ways to use it, but that is the pattern it was designed for.
Setting Attributes at the Same Precedence Level
A common use case is to set default attributes in a cookbook's attribute files, and also set the same default attributes, but with different values, using a role. In this scenario, the attributes set in the role will be deep merged on top of the attributes from the attributes file. The attributes set by the role will win if there is a conflict.
Setting a Value Only If the Attribute Has No Value
In attribute files, you can also set a value only if no value is currently set for that attribute using the