Skip to end of metadata
Go to start of metadata

Overview

Chef Cookbooks require you to specify a small amount of meta-data. This information is used to provide hints to the Chef Server as to what cookbooks should be deployed to a given node, and in the future it will be integral to an automated system for discovering and installing cookbooks.

To get started, you need to create a metadata.rb file at the top of your cookbook. This file provides a simple ruby DSL for building the actual metadata file (which is stored as JSON). If you create a new cookbook by using knife cookbook create command, a template metadata.rb file will be created for you.

metadata.rb

We never interpret the metadata file directly, we only ever use the compiled JSON file! Currently, the metadata JSON is generated for you when you upload the cookbook or run the knife cookbook metadata COOKBOOK command. It's a good practice to always edit metadata.rb but not the JSON file, but if you need to edit metadata.json directly, remember that it will be overwritten by metadata.rb next time when you generate metadata or upload cookbook using knife, if metadata.rb exists.

At the moment, we utilize the following fields in the metadata:

  • maintainter
  • maintainer_email
  • license
  • description
  • long_description
  • depends
  • version
  • recipe

Meaningful Fields

The following fields are used by the Chef Server, WebUI, or Opscode Community Site.

name

The name of the cookbook. Normally this is inferred, but you can override it here.

name example


Did you get sent here by an error message?

If so, here is the deal. The Chef Server tries to only distribute the cookbooks that are needed to configure each individual Node. In order to do that, we take the list of Roles and Recipes that are assigned directly to that system, expand the list of dependencies for them, and then ship that set to the Node.

If you forget to specify a dependency in a cookbooks metadata, then the Chef Server will not realize that the cookbook is necessary to complete your configuration... resulting in the error message that brought you here. To fix it, simply add the right 'depends' entry to your metadata.rb file and try again.



version

The current version of this cookbook. Version numbers follow the simple three-number version scheme:

version example

depends

Adds a dependency on another cookbook, with version checking strings. This will require that you have a cookbook with the proper name, and a version number that matches.

Whenever you include a recipe in a cookbook via "include_recipe" you need to add the included cookbook to the depends list.

Make sure this is accurate!

This is a critical piece of information - the Chef Server uses these dependency statements to ensure that the right cookbooks are distributed to the edge. Failure to properly fill out this field will result in Chef not completing, or partially completing, the configuration of your system!

The 'depends' are only used if you apply the recipe in a role, or directly to a node. If a cookbook doesn't depend on any others, that's okay.

Version Syntax

Version constraints are fully documented on their own page. The syntax is summarized here.

Operator

Description

<

Less than

<=

Less than or equal to

=

Equal to

>=

Greater than or equal to

~>

Approximately greater than

>

Greater than

Examples

depends examples

In the actual recipe, the "depends dogs" is required for either:

description

A short description of this cookbooks function. Ideally a single line.

license example

long_description

A longer description of this cookbook. Ideally contains full instructions on the proper use of this cookbook, descriptions of definitions it contains, libraries, etc. Often rendered from README.rdoc at the top of the cookbook.

long_description embedded example
long_description read in a file example

maintainer

This is the name of the current maintainer - it should be either an individual or an organization.

maintainer example

maintainer_email

This is the email address of the current maintainer.

maintainer_email example

license

This is the license the cookbook is distributed under.

license example

Optional Fields

The following fields are optional. The information in these fields is not used by the Chef server.

attribute

Adds an attribute that a user may need to configure for this cookbook. Takes  a name (with the / notation for a nested attribute), followed by any of  these options:

Option

Possible Values

Descriptions

display_name

String

What a UI should show for this attribute

description

String

A hint as to what this attr is for

choice

Array of strings

Array of choices to present to the user. If type is string, allow user one choice. If type is array, allow user many choices.

calculated

true or false

If true, the default value is calculated by the recipe and cannot be displayed.  If value != nil, calculated default will be overwritten.

type

"string", "array"

The type of value passed to the recipe - default is "string". 

required

"required", "recommended", "optional"

The level of user input this attribute requires - default is "optional"
"required" : User must provide input. The "default" option must not be set.
"recommended" : A default value is set, but the user probably should change it. (i.e. apache[:contact] = "ops@example.com")
"optional": Default values are set and there is no need to change unless the user knows what they are doing.
For backwards compatibility,
  "required: true" is interpreted as "required: required" and
  "required: false" is interpreted as "required: optional"

Note: at present, the required attribute is advisory-only and is not enforced by Chef: if necessary, your recipe should check that the attribute is set and raise an exception if it is not.

recipes

Array

An array of recipes which need this attr set. If not set, the attribute is global to recipes in "this" cookbook

default

String , Array

The default value for this attribute. This value(s) must exist in any non-empty 'choice' array. Do not define if 'calculated' is true.

attribute description

grouping

Adds a displayable title and description to a group of attributes within a namespace. Takes a name (with the / notation for a nested grouping), followed by any of these options:

Option

Possible Values

Descriptions

title

String

Title for this group of attributes

description

String

A hint as to what these attributes are for

attribute grouping description

conflicts

Warns that this cookbook conflicts with another cookbook.

conflicts examples

provides

Adds a recipe, definition, or resource provided by this cookbook. We auto-populate the list of provided recipes, so it would be rare to need to specify them directly.

Recipes are specified as expected:

provides a recipe

Definitions are defined by using the name of the definition, followed by parenthesis, and a symbol-style list that matches the definitions parameters.

provides a definition

Individual resources are specified with the normal stringified resource syntax:

provides a resource

recipe

Adds a description for a recipe - used mainly for aesthetics in the UI.

recipe description

recommends

Adds a dependency on another cookbook that is not required (ie: we'll work without it) but is a good idea.

supports examples

replaces

This cookbook replaces another - it can be used entirely in the place of it.

replaces examples

supports

Adds a supported platform, with version checking logic. To specify multiple platforms, simply provide this command multiple times, once for each platform.

If no version is provided, any version of the platform will match.

supports examples

Currently, the platform matching and version checking logic is not implemented - Chef will happily run any cookbook on any platform, regardless of the data provided here.

suggests

Adds a suggestion for another cookbook. The difference between recommends and suggests is that, should a system be constructed for automatically resolving cookbook dependencies, recommended cookbooks will be included by default, and suggested ones will not.

supports examples


Labels
  • None
  1. Jun 02, 2009

    Looks great so far!!!

    Any intention of adding a service to the depends field? For example, I may want my MySQL cookbook to require a 'disk' provider like LVM?

    Good work(wink)

    1. Jun 03, 2009

      Yeah - we should update the documentation to reflect it, but I imagine you would do something like:

      depends on a resource

      Similarly, for a definition (ie: you want to just call something to setup your disks:

      depends on a definition

      The above would verify that a definition exists with those params being valid.

  2. Jun 04, 2009

    Just thinking about how my UI would digest this information and create a display...

    Here's my use case:
    I don't want to show every possible attribute in the recipe - that would be overwhelming to the user. Ideally, I would only show the absolute minimum attributes required for a cookbook to run. However, the user may still like to drill down into some 'optional' and/or 'advanced' attributes. (maybe there are other classifications? like 'recommended'? e.g. apache[:contact])

    The definition for a metadata attribute field, from above, is "Adds an attribute that a user needs to configure for this cookbook". Can this also be used for specify optional attributes? I'm a bit confused regarding the purpose of the "required" field if all attributes "need" to be set. I am also confused why a "default" value would be specified if it is required to be set by the user.

    1. Jun 04, 2009

      We should definitely allow you to specify optional attributes. In my mind, that was the purpose of the 'required' field, but that only gives you two levels of control: either you must specify it, or you may not. No extra information like "optional", "advanced" or "recommended".

      I'm updating the wiki to reflect that not all the attributes are required. Cary, it would be great if you could post an example of how you would like to see the attribute meta-data extended to fit your requirements.

    2. Jun 04, 2009

      The "required" property specifies whether an attribute must have a value. If a default value is provided, then in effect a value is always provided. The purpose of this property is to avoid launching servers in a situation that is guaranteed to fail because attributes are missing. So an attribute which is not required but for which there's a default value is a bit odd, except that you could go in and specifically erase the default value and it'd be ok. This raises the question of whether a distinction is made between "empty=nil" and "not specified". It also raises the question about where defaults are filled in. Is this something that is supposed to be done on the server end, is it done when chef client starts, or is it supposed to be done in the cookbook code itself? It would be good to avoid creating inconsistencies between the metadata and the cookbook code...

      The other aspect that is not captured is that we see a real tension with respect to the number of attributes. It's really good for first time users to be able to "just plop down apache" having to focus only on a couple of required attributes they need to set. But there's also the advanced users that come along with a "if only you had this optional attribute then I would have to fork the cookbook to get this little change in". I'm wondering whether we should change the "Required" field from boolean to "required"/"optional"/"ancillary" (or "adanced"). We could have a separate "display_priority" property but required attributes should be top priority, so these are not really orthogonal.

  3. Jun 04, 2010

    After initial release of our UI it has become clear that some changes would make our life easier. Summary of proposed changes:

    1. Clarify the meaning of "type" option to simply: "the type of value passed to the recipe".
    2. "hash" type seems not a value at all, but a "section" or "grouping" of values. To avoid the confusion, let's make a new metadata field altogether (below a "grouping" field is suggested).
    3. replace the 'multiple_values' option, with the 'choice' option (choices are always of type "string")
    4. If type is string, allow user one choice. If type is array, allow user many choices. "choice" is an array of strings.
    5. Change "required" option from boolean to preset levels
    6. Add a boolean "calculated" option for those times when a default is impossible to predict because it is calculated somewhere in the recipe. However, exposing this attribute allows the user to override the calculation.

    Below is the modified wiki sections that contain these proposals....


    <snip>

    attribute

    Adds an attribute that a user may need to configure for this cookbook. Takes  a name (with the / notation for a nested attribute), followed by any of  these options:

    Option

    Possible Values

    Descriptions

    display_name

    String

    What a UI should show for this attribute

    description

    String

    A hint as to what this attr is for

    choice

    Array of strings

    Array of choices to present to the user. If type is string, allow user one choice. If type is array, allow user many choices.

    calculated

    true or false

    If true, the default value is calculated by the recipe and cannot be displayed.  If value != nil, calculated default will be overwritten.

    type

    "string", "array"

    The type of value passed to the recipe - default is "string". 

    required

    "required", "recommended", "optional"

    The level of user input this attribute requires - default is "optional"
    "required" : User must provide input. The "default" option must not be set.
    "recommended" : A default value is set, but the user probably should change it. (i.e. apache[:contact] = "ops@example.com")
    "optional": Default values are set and there is no need to change unless the user knows what they are doing.
    For backwards compatibility,
      "required: true" is interpreted as "required: required" and
      "required: false" is interpreted as "required: optional"

    recipes

    Array

    An array of recipes which need this attr set. If not set, the attribute is global to recipes in "this" cookbook

    default

    String , Array

    The default value for this attribute. This value(s) must exist in any non-empty 'choice' array. Do not define if 'calculated' is true.

    attribute description

    grouping

    Adds a displayable title and description to a group of attributes within a namespace. Takes a name (with the / notation for a nested grouping), followed by any of these options:

    Option

    Possible Values

    Descriptions

    title

    String

    Title for this group of attributes

    description

    String

    A hint as to what these attributes are for

    attribute grouping description

    </snip>

    Adopted in v0.8.x -- Updated page with the above info. 6/4/2010

  4. Oct 08, 2009

    For backwards compatibility, "required: true" is interpreted as "required: required".

  5. Jan 18, 2010

    Some kind of i18n at this level would make sense

    :display_name =>"Cat Name",

    :display_name _de =>"Name der Katze",

    or

    :display_name => {"Cat Name", :translations => { :de => "Name der Katze"}}

    yml files could be calculated to something like

    pets_cat_display_name =