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:

  • maintainer
  • 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 in the cookbook metadata.

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

Declares that this cookbook has a dependency on another cookbook, with an optional version constraint. This will require a cookbook with a matching name and version number to exist on the server, and will cause the server to include it in the set of cookbooks sent to the node when the chef-client runs.

Whenever you need to use a feature in another cookbook, it is a dependency and you need to add the included cookbook's feature to the depends in the current cookbook. For example, including recipes with "include_recipe", resources/providers in LWRPs, libraries, or definitions.

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 syntax and constraints are fully documented on their own page. In summary:

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, "depends dogs" is required for either.

See Version Constraints for more information on the version syntax, and how the cookbook metadata can be used to limit the version of the cookbook that should be used.

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. You can only list one address here, but if you need this to forward to multiple people consider placing a mailing list here that is already setup to forward.

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







Libraries


Recipes



Labels:
None
Enter labels to add to this page:
Please wait 
Looking for a label? Just start typing.
  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

    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 =

  6. Jun 30, 2011

    I'm finding the attribute definitions and groupings to be extremely useful. I've written a utility script to aid in composing role and node attributes based on the defined metadata attributes and groupings. It's coming along great. It parses the metadata.json groupings and attributes into command line user input widgets, e.g. yes/no, true/false, multiple choice, text string, etc. A few things that I think would be really useful would be a way to order groupings and attributes and to be able to define dependencies on other attributes. My current use case is mysql. For example, if auto-tune is true, there is no need to ask about buffer tuning sizes. another example is if innodb support is false, then don't bother asking about innnodb buffer pool settings and such.

    I'm imagining ordering and dependencies could be defined as such...

    metadata.rb example

    Of course it'd be up to the programmer to properly display things in order since json is not ordered. I'm sure someone smarter than me could also come with a better/more flexible way to define dependencies and behavior based on dependencies, but you catch my drift.

    UPDATE...

    I noticed that I can stick whatever I want in the definitions and it just works (meaning it appears in the metadata.json). I'm reworking my code to obey the "order" and "depends" to see how it all works out.

    Will this behavior remain? I mean will I always be able to arbitrarily add my own variables into the grouping and attribute definitions and have them appear in the metadata.json without breaking things?

  7. Jul 17, 2011

    Can the maintainer and maintainer_email contain more than one person? What is the recommended way to convey the fact that I forked the cookbook but I want to have the original person in there as well as myself.

    1. Jul 20, 2011

      Hello Robert,

      You can only have one person as the maintainer and maintainer_email. You could however list the maintainer as something like "Runa Administrators" and then put a mailing list as the maintainer_email that is forwarded to multiple people.

      There is a bit of information on this in our How to Contribute Wiki Article as well:

      "How should I update the header file of my contribution to properly credit earlier contributors and recognize copyrights?

      You need to put attribution about the origins of some of the code in the NOTICE file for your app. On an individual header, you can add yourself as an author/copyright holder, placing text in the header file saying that your new work is based on previous work, and referencing the original header below.

      If the original file is lacking the license header, please let us know, so we can add one. Even in their absence, they are covered by the Apache 2 license."

      You could also place this information in the description, or the readme.md if you'd like it noted in any additional places. Feel free to update this ticket if you have any further questions for us about this.

      Thanks,
      Jessica