|
Attributes in a Cookbook allow you to set various Attributes on a node, which you can then access from within the recipe. Good candidates for Attributes are:
The last bullet is important - attributes are persisted between Chef runs. When you next run Chef, your Node will load the attributes from the Chef Server exactly as they were at the end of your last run. This also means that you may need to guard against overwriting an attribute that has been modified by an administrator (via the Node section of the Web UI). |
Dissecting an Attribute file
Below is a sample Attribute file from an Apache cookbook. It shows how you might use an Attribute file for data that provides a Cross-Platform abstraction (but is not about the Operating System - if it was, it belongs in Ohai).
|
Sample Attribute File |
|
set and set_unless are new methods that can be used to set attributes, and default is an alias for set_unless (think: set a default value, unless one exists). Note that we didn't have to set up 'apache' first, it is auto-vivified by the method. Alternately, you can use "chained method" notation, which may be more comfortable to Ruby programmers. As an example using the last set_unless from above:
Also, we no longer need to specify a "Mash" object, as that is automatically created (a Mash is a Hash that can interchangably use symbols instead of strings for keys).
Next, we use a case statement on the platform attribute to set some default attributes. We don't worry about making sure we don't overwrite these attributes - if they change, it's because the nodes platform has changed - and that means they should change.
Finally, we have some attributes that we intend to be tunable: apache[:listen_ports] and apache[:contact]. These attributes check whether or not the apache attribute we set earlier has a value set - if it does, we aren't going to replace it.
Setting up extra Recipes
In addition to attributes, you can set up additional recipes that the node should run from within an Attribute file. You do it like this:
This makes sure that the extra recipe is applied to this node, but doesn't add it to the list if it is already present.
Attribute file ordering
When Chef loads cookbook attribute files, it does so in alphabetical order by default. 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 include_attribute, like so:
Would load apache/attributes/default.rb before continuing the processing of the current attribute file.
The syntax for this follows the same pattern as include_recipe, so a statement like:
Would look for the attributes/tunables.rb file in a rails cookbook.
Attributes in JSON
You can also specify attributes to use on a node with a JSON file.
For example, to set up some different ports for Apache to listen on:
This is the equivalent to:
Methods
The following are some handy methods for use within Attribute files.
attribute?("name")
Checks for the existence of a top level attribute.
Returns true if the attribute exists, false if it does not.
recipe?("name")
Checks for the existence of a recipe.
Returns true if the recipe is being applied to this node, false if it is not.
Note that attributes will be processed regardless of whether the recipe is active for a given node - i.e., if you want attributes to be ignored unless a recipe is active, do something like this: