Skip to content
Fetching contributors…
Cannot retrieve contributors at this time
533 lines (350 sloc) 13.2 KB

Adding Cookbooks

.notes These course materials are Copyright © 2010-2012 Opscode, Inc. All rights reserved. This work is licensed under a Creative Commons Attribution Share Alike 3.0 United States License. To view a copy of this license, visit; or send a letter to Creative Commons, 171 2nd Street, Suite 300, San Francisco, California, 94105, USA.


At completion of this unit you should...

  • Understand how knife handles merging multiple cookbooks.
  • Understand recipe ordering.
  • Apply multiple recipes to a node through a role.
  • Be able to create a new cookbook and start writing simple recipes.

Getting More Cookbooks

Knife can download more cookbooks.

knife cookbook site install apt
knife cookbook site install apache2

When using Git, multiple cookbooks are committed to the repository.

Git Commit Log

% git log commit 49e45373f294ace0c721a98f2155d4d2b558fee8 Author:
jtimberman <> Date: Tue Apr 26 15:27:53 2011

   Import apt version 1.1.1

commit 5ead5af876235c0e7bc37972ea22134cd10af7ba Author: jtimberman
<> Date: Tue Apr 26 12:45:57 2011 +0000

    Import fail2ban version 1.0.0

Git Branches

% git branch

Git Tags

% git tag

Infrastructure as Code

This is a source code repository.

Treat it like one!

We can go back to any point in time, any version of a cookbook, and inspect differences.

Comparing Differences

git checkout chef-vendor-apt
git checkout chef-vendor-fail2ban-1.0.0
git diff master

Use Your VCS

Knife currently integrates with Git in the “cookbook site install” command.

You can use any version control system you like.

There will be additional steps required to untar cookbooks, branch/merge, etc, depending on your tool.

Open Source contributions welcome!

Recipe Ordering

Recipes applied to a node are processed in the order specified.

Recipes are specified in a Role or Node run list.

Run lists are ordered lists (Ruby/JSON arrays).

Recipe Ordering

Recipes can include other recipes, too. Use “include_recipe”

Chef will process the included recipe in place, adding its resources to the resource collection.

Included recipes from other cookbooks require metadata dependency.


Cookbook dependencies are implied when using part(s) of one cookbook in another, such as recipe inclusion.

Cookbook dependencies are explicitly defined in metadata.

Use the “depends” keyword in the metadata.

Cookbook Metadata

The metadata defines the additional cookbooks required that might not appear in the run list explicitly.

The server reads the metadata as JSON, it does not parse the recipes (which are Ruby).

This is a security feature, the Chef Server does not execute the Ruby code.

Run Lists

During the initial part of the Chef run the node’s run list is expanded. Roles' run lists are expanded.

Chef uses the expanded run list to determine what recipes are included, and which cookbooks to download from the server.

Dependencies in the metadata are also downloaded.

Cookbooks are versioned. If the node has a Chef Environment, and the environment specifies cookbook versions, those versions will be downloaded.

Using Roles

We typically apply multiple related recipes to a node via a role.

A base role is a great place to apply the 'fail2ban' recipe, and also a recipe to update the APT cache on Debian/Ubuntu systems.

Simple Base Role

name "base"
description "Base role is applied to all systems"

Order Matters

We’ll put apt before fail2ban to make sure the package cache is updated.

The default action in the fail2ban package resource is upgrade, so apt will ensure we always have the latest version including security fixes.

Upload Base Role

Use knife to upload the base role.

knife role from file base.rb

This will look for the role file (base.rb) in the roles sub-directory of the Chef Repository.

Apply Role to a Node

First remove the fail2ban recipe, it will be applied via the base role.

knife node run list remove NODE ‘recipe[fail2ban]’

Then add the role to the node.

knife node run list add NODE ‘role[base]’

Run chef-client

Running Chef on the target node will cause the APT recipe to be applied, then fail2ban.

Since fail2ban was applied previously, it will not actually take any action on the node (unless there’s a new package version!).

Creating Cookbooks

New cookbooks can be created with Knife.

This will create a skeleton directory structure with all the components of a cookbook.

knife cookbook create

% knife cookbook create webserver
** Creating cookbook webserver
** Creating README for cookbook: webserver
** Creating metadata for cookbook: webserver

Default Cookbook Contents

tree cookbooks/webserver
├── README.rdoc
├── attributes
├── definitions
├── files
│   └── default
├── libraries
├── metadata.rb
├── providers
├── recipes
│   └── default.rb
├── resources
└── templates
    └── default

Pre-generated Content

Knife pre-generates some information in the cookbook.

  • README.rdoc
  • metadata.rb
  • recipes/default.rb

The values used come from configuration options in the knife cookbook create command.

Configure Knife

Knife is not configured for creating new cookbooks by default. It has three settings that can customize the pre-filled content.

  • cookbook_email
  • cookbook_copyright
  • cookbook_license

knife cookbook create

cookbook_copyright "Opscode, Inc."
-C, --copyright COPYRIGHT

cookbook_license "apachev2"
-I, --license LICENSE

cookbook_email ""
-E, --email EMAIL

Used to prefill default recipe, README and metadata

cookbook_* goes in knife.rb, and corresponds to command-line options

Licenses available: apachev2, gplv2, gplv3, mit, none

Note About Software Licenses

Cookbooks are distributable, be careful about the software license you choose.

You can use whatever you like.

Be aware of what you include in your cookbook, though!

Opscode uses Apache 2.0 Software License. Use the license you prefer.

  • This is not legal advice, ask a lawyer if unsure.

Modifying the Cookbook

Once the cookbook is created, it is time to start modifying it to do something meaningful.

Typically, this will involve editing the default recipe.


Edit this with your favorite text editor.

Cookbook Components

Not all the cookbook components are used.

They are created so you don’t have to remember them all.

Remove the ones you know you don’t want.

Common Cookbook Components

The most common cookbook components:

  • attributes
  • recipes
  • metadata
  • README :)
  • files and / or templates

Cookbook Attributes

Cookbook attributes files set up sane defaults to be used in the cookbook.

We will cover them in depth next unit.

Cookbook Recipes

Most things in Chef recipes will be resources to configure.

Some things in Recipes will be pure Ruby syntax and helper code.

Your first recipes will be simple.

Ruby DSL

A DSL is a domain-specific language

  • Recipes are a pure Ruby DSL
  • Recipes are processed in two phases
  • Compilation and Execution happen in the order specified.

Attributes in Recipes

The node object is available in recipes, and we can access the attributes like a Ruby hash key.

  • node['fqdn']
  • node['kernel']['machine']

Attributes can come from cookbook files, roles, or the node itself.

Common Chef Resources

Chef supports a couple dozen resources, but a few are most commonly used. We’ll mostly work with the common ones.

  • package
  • service
  • template, cookbook_file, remote_file
  • user
  • execute

Common Resources: Package

package "tar" do
  action :install

package "tar" do
  version "1.16.1-1"
  action :install

package "tar" do
  action :upgrade

package "tar" do
  action :remove

Common Resources: Service

service "example_service" do
  supports :status => true, :restart => true, :reload => true
  action [ :enable, :start ]

.notes Recall the 'supports' meta-parameter controls the way the service's provider is going to work with the service on the system. :status => true, Chef will use the built in status command for the provider to check if the service is running. Commonly this is like '/etc/init.d/SERVICE status.' :restart => true, Chef will use the built in restart command for the provider to restart the service. Commonly this is like '/etc/init.d/SERVICE restart.' :reload => true, Chef can send a reload action to a service only if it supports reload. Chef will use the reload command for the provider usually to tell the daemon about a configuration change. Commonly this is like '/etc/init.d/SERVICE reload.'

Common Resources: Template

# Config file from a template
template "/tmp/config.conf" do
  source "config.conf.erb"

# Config file from a template with variable map
template "/tmp/config.conf" do
  source "config.conf.erb"
    :config_var => node["configs"]["config_var"]

Common Resources: Cookbook File

cookbook_file "/usr/local/bin/" do
  source ""
  mode 0755
  owner "root"
  group "root"

Common Resources: Remote File

remote_file "/tmp/testfile" do
  source ""
  mode "0644"
  checksum "08da002l"

Common Resources: User

user "random" do
  comment "Random User"
  uid "1000"
  gid "users"
  home "/home/random"
  shell "/bin/zsh"
  password "$1$JJsvHslV$szsCjVEroftprNn4JHtDi."

# System User
user "systemguy" do
  comment "system guy"
  system true
  shell "/bin/false"

.notes For password setting, you need to generate the password appropriate for your system.

Common Resources: Execute

execute "generate-module-list" do
  command "/usr/local/bin/ /usr/lib/httpd/modules /etc/httpd/mods-available"
  action :run

The command parameter calls a cookbook_file dropped off by an earlier example.

Providers Take Idempotent Actions

Providers know how to run the right commands or API calls to configure a resource by taking the appropriate action.

Providers should be written so they are idempotent and don’t configure the resource if it is in the declared state.

Providers are sometimes platform specific (apt, yum, useradd, chkconfig, etc).

Cookbook Metadata


  • Information about the cookbook
  • Instructs server what to distribute (dependencies)
  • Specifies the version
  • “Packaging” information

Cookbook Metadata

Use metadata to define dependencies.

Dependencies are required when using a cookbook’s components in another cookbook.

depends “classroom”

Cookbook Metadata

maintainer       "YOUR_COMPANY_NAME"
maintainer_email "YOUR_EMAIL"
license          "All rights reserved"
description      "Installs/Configures webserver"
version          "0.0.1"
depends          "apache2"

Cookbook Assets

Cookbooks have two kinds of assets that aren’t strictly Ruby code that can be distributed.

  • Files (cookbook_file resource)
  • Templates (template resource)

Cookbook Assets: Files


  • Static assets
  • file, cookbook_file, remote_file resources
  • For directories, remote_directory resource
  • File specificity

.notes "file" is a basic resource that manages the properties of a file - owner, mode, and basic content. "cookbook_file" is a file distributed from the cookbook. "remote_file" is a file downloaded from a remote source. An early common development pattern is to start using cookbook_file for static configuration files.

Cookbook Assets: Templates


  • Dynamic
  • ERB (embedded ruby)
  • Access to node and variables
  • template resource
  • File specificity

.notes Templates are dynamically rendered by Chef during convergence. The content of the rendered template is compared via SHA256 checksum to the target file. Variables can be passed into the template resource as a parameter. The node object is accessible in a template as well.

File Specificity

File specificity is how Chef determines source file for files and templates

Directory locations under files or templates

  • host-FQDN
  • default

File Specificity Example

% ls cookbooks/classroom/files/*


You should now be able to...

  • Explain how knife handles merging multiple cookbooks.
  • Describe recipe ordering through inclusion.
  • Apply multiple recipes to a node through a role.
  • Create a new cookbook and understand the components.

Lab Exercise

Adding Cookbooks

Jump to Line
Something went wrong with that request. Please try again.