Recipes are the fundamental configuration in Chef. Recipes encapsulate collections of resources which are executed in the order defined to configure the system
|
|
Applying Recipes to NodesIf you are using Chef with client/server, use knife to add the recipe to the node's run list, then run Chef client on the node. If you are using Chef Solo, use a JSON file passed to chef-solo -j: /etc/chef/dna.json Then run chef-solo: The cookbooks must be available in the cookbook_path on the system running chef-solo. See the Chef Solo page for more information. ResourcesChef manages Resources on the node. Resources can be many things:
And more. They are the bread and butter of recipes. Chef's Providers do the heavy lifting that configure resources, based on the platform of the node. Chef's providers take idempotent actions to configure the resource as it is declared in the recipe. CompositionResources have four components:
For example: This resource is a Ruby block. Its type is "package". Its name is "tar". It has a single parameter attribute "version". It defines a single action, ":install". Parameter attributes are not the same as node Attributes. Context is important. These parameters specify various ways the resource should be configured. Each kind of resource in Chef has different parameters, and some have default values. If you want the default, you do not need to specify that parameter. Likewise, each type of resource has a default action. You do not need to specify the action if you want the default. See the Resources page for documentation on each resource that comes with Chef and the default parameters and actions. Meta ParametersA variety of "meta" parameters are available to all resources. These are most commonly used to send notifications to other resources or set up conditional execution rules. Meta parameters are documented in detail in the Meta section of the Resources page. Custom Lightweight Resource Providers (LWRPs)As discussed above, Resources represent a piece of system state and Providers are the underlying implementation which brings them into that state. For example, all database vendors support the abstract concept of database creation, but the underlying implementation is different for each. While typical Resources and Providers are implemented in Chef's core using Ruby classes, creating custom Lightweight Resources and Providers (LWRP) requires less Ruby knowledge than their heavier counterparts. For the Light-weight Resources and Providers (LWRPs) that are used in Opscode's public open source cookbooks, see Opscode LWRP Resources. Node ObjectRecipes are executed in the context of the Chef node object, called node. A feature of Chef is using data about the Node, called Attributes in recipes to configure the system in particular ways based on that data. Accessing Node AttributesThe node's attributes are like a Ruby hash. They are accessed with: This will use the value of 'some_attribute'. A number of attributes are detected automatically by ohai when the node runs Chef. Node attributes are a nested key/value store, so there can be sub-keys too: New custom attributes can be created in Cookbook Attributes and Roles. See below for creating new attributes in Recipes. Common Automatic AttributesOhai detects attributes on the node based on its own plugin system. The most commonly accessed attributes are:
Automatic Attributes lists all the automatic node attributes detected by Ohai. Additional attributes and sub-attributes can be viewed on a particular node by running ohai. This returns data as JSON. Setting Node AttributesNode attributes can be set in recipes. This use of node attributes should do done when you want to calculate a derived value, or store some data on the node that should be persisted the next time Chef runs. Use the "set" method on the node. Attributes are applied in precedence order; node attributes are automatic and have the highest precedence. As these automatic attributes will be re-written with each Ohai run - Chef doesn't provide any way to modify them. See Setting Attributes for more detail on the attribute types and precedences. Including RecipesRecipes from other cookbooks can be included in a recipe with the include_recipe keyword. The included recipe's resources will be inserted in order, at the point where include_recipe was called. For example: Will include the resources defined in recipe apache2::mod_ssl. Note, however, that subsequent calls to include_recipe for the same recipe will have no effect. You can also pass data from various recipes to one definition. This would be useful if you'd like to update your /etc/aliases, /etc/sudoers, or something similar, with entries from multiple recipes in a single chef run. |
DependenciesWhen using Chef client/server, you must use cookbook Metadata to declare dependencies on cookbooks' recipes included with include_recipe. This is specified with the "depends" keyword in the metadata.rb of the cookbook. For example, if the above inclusion of apache2::mod_ssl was in a recipe in the "my_app" cookbook then cookbooks/my_app/metadata.rb would have: This is not required in Chef Solo because all the cookbooks the node will use must be available since Solo doesn't use a Chef Server to distribute cookbooks. |
|
Other Data SourcesThe Chef Server has core features that are useful in Recipes to build fully automated dynamic infrastructure. The Chef Recipe DSL has keywords for using each of these features. SearchA basic search query in a recipe looks like this: Searches can be assigned to variables and then used elsewhere in a recipe. For example, we could search for all nodes with the role "webserver" assigned, then render a template with them. For more information on using search in recipes, and search queries in general, see the Search documentation. For more information on the Template resource, see its section on the Resources#Template page. Data BagsThe Chef Server can have arbitrary stores of JSON data called Data Bags, which can also be Encrypted Data Bags. Each bag is a container of one or more items. These items can be loaded in recipes. Given the bag "apps", and the following item "my_app": We can access the item in a recipe: The item's keys and values can be accessed like a Ruby Hash. Other Recipe DSL MethodsThere are other methods available in the Recipe DSL. platform?The platform? method will return true if one of the parameters matches the node 'platform'. This method takes a comma separated list of platforms. attribute?The node.attribute? method will return true if the specified node attribute is defined. value_for_platformThe value_for_platform method uses a hash to select a particular value based on the node 'platform' and node 'platform_version'. value_for_platform syntax For example, the following will set the package_name Ruby variable to "httpd" on Red Hat family distributions, or "apache2" on Debian family distributions. value_for_platform example TagsTo use tags in your recipe simply If you want to test if a machine is tagged will return true or false. tagged? Takes an array as an argument. To remove a tag So all in all Will output Ruby in RecipesRegular Ruby code can also be used in Chef Recipes. VariablesAssign values to variables in recipes using the assignment operator, "=" ConditionalsCommon conditionals can be used to check for true/false. Note that in Ruby, only nil and false are false, everything else is true. CaseSelect a particular package name for a resource based on the platform. This is similar to the example above. If/UnlessIf statements check for true or false values. Unless is the opposite of if. LoopsUse the .each method to an Enumerable object (typically an Array or Hash) ArrayIterate over an array of package names and install them. HashIterate over a hash of gem package names with specific versions. Further Reading
|
|
|


1 Comment
comments.show.hideJan 23, 2012
Robert J. Berger
It would be nice to add something about how to handle errors and logging. Like whats the appropriate way to generate an error exception or exit if the recipe test decides that something is bad and should immediately exit the chef-client run.
Another case that I always forget how to do in Chef is to stop processing a recipe but not be an error. Just short-circuit that recipe to return/exit and allow the chef-client run to continue.
And it might be good to put in this recipes page how to do logging with Chef::Log as well as any other normal non-resource but Chef specific things like logging and exception generation...