Chef

Table Of Contents

About the chef-repo

The chef-repo is the location in which the following data objects are stored:

  • Cookbooks (including recipes, versions, cookbook attributes, resources, providers, libraries, and templates)
  • Roles
  • Data bags
  • Environments
  • Configuration files (for clients, workstations, and servers)

The chef-repo is located on a workstation and should be synchronized with a version control system, such as git. All of the data in the chef-repo should be treated like source code.

knife is used to upload data to the Chef server from the chef-repo. Once uploaded, that data is used by the chef-client to manage all of the nodes that are registered with the Chef server and to ensure that the correct cookbooks, environments, roles, and other settings are applied to nodes correctly.

Directory Structure

The chef-repo contains several directories, each with a README file that describes what it is for and how to use that directory when managing systems.

Note

This document describes the default directory that is present in most instances of the chef-repo.

The sub-directories in the chef-repo are:

Directory Description
.chef/ A hidden directory that is used to store .pem files and the knife.rb file.
cookbooks/ Contains cookbooks that have been downloaded from the https://supermarket.getchef.com/cookbooks or created locally.
data_bags/ Stores data bags (and data bag items) in JSON (.json).
environments/ Stores environment in Ruby (.rb) or JSON (.json).
roles/ Stores roles in Ruby (.rb) or JSON (.json).

.chef/

The .chef/ directory is a hidden directory that is used to store .pem validation that are provided by the Chef server and a knife.rb file. These files are required for interaction with a Chef server.

cookbooks/

The cookbooks/ directory is used to store the cookbooks that are used by the chef-client when configuring the various systems in the organization. This directory contains the cookbooks that are used to configure systems in the infrastructure. Each cookbook can be configured to contain cookbook-specific copyright, email, and license data.

data_bags/

The data_bags/ directory is used to store all of the data bags that exist for an organization. Each sub-directory corresponds to a single data bag on the Chef server and contains a JSON file for each data bag item. If a sub-directory does not exist, then create it using SSL commands. After a data bag item is created, it can then be uploaded to the Chef server.

environments/

The environments/ directory is used to store the files that define the environments that are available to the Chef server. The environments files can be Ruby DSL files (.rb) or they can be JSON files (.json). Use knife to install environment files to the Chef server.

roles/

The roles/ directory is used to store the files that define the roles that are available to the Chef server. The roles files can be Ruby DSL files (.rb) or they can be JSON files (.json). Use knife to install role files to the Chef server.

chefignore Files

The chefignore file is used to tell knife which cookbook files in the chef-repo should be ignored when uploading data to the Chef server. The type of data that should be ignored includes swap files, version control data, build output data, and so on. The chefignore file uses the File.fnmatch Ruby syntax to define the ignore patterns using *, **, and ? wildcards.

  • A pattern is relative to the cookbook root
  • A pattern may contain relative directory names
  • A pattern may match all files in a directory

The chefignore file is located at the root of the /cookbooks subdirectory in the chef-repo. It should contain sections similar to the following:

# section
*ignore_pattern

# section
ignore_pattern*

# section
**ignore_pattern

# section
ignore_pattern**

# section
?ignore_pattern

# section
ignore_pattern?

Examples

The following examples show how to add entries to the chefignore file.

Ignore editor swap files

Many text editors leave files behind. To prevent these files from being uploaded to the Chef server, add an entry to the chefignore file. For Emacs, do something like:

*~

and for vim, do something like:

*.sw[a-z]

Ignore top-level Subversion data

If Subversion is being used as the version source control application, it is important not to upload certain files that Subversion uses to maintain the version history of each file. This is because the chef-client will never use it while configuring nodes, plus the amount of data in an upload that includes top-level Subversion data could be significant.

To prevent the upload of top-level Subversion data, add something like the following to the chefignore file:

*/.svn/*

To verify that the top-level Subversion data is not being uploaded to the Chef server, use knife and run a command similar to:

$ knife cookbook show name_of_cookbook cookbook_version | grep .svn

Ignore all files in a directory

The chefignore file can be used to ignore all of the files in a directory. For example:

files/default/subdirectory/*

or:

files/default/subdirectory/**

Many Users, Same Repo

It is possible for multiple users to access the Chef server using the same knife.rb file. (A user can even access multiple organizations if, for example, each instance of the chef-repo contained the same copy of the knife.rb file.) This can be done by adding the knife.rb file to the chef-repo, and then using environment variables to handle the user-specific credential details and/or sensitive values. For example:

current_dir = File.dirname(__FILE__)
  user = ENV['OPSCODE_USER'] || ENV['USER']
  node_name                user
  client_key               "#{ENV['HOME']}/.chef/#{user}.pem"
  validation_client_name   "#{ENV['ORGNAME']}-validator"
  validation_key           "#{ENV['HOME']}/.chef/#{ENV['ORGNAME']}-validator.pem"
  chef_server_url          "https://api.opscode.com/organizations/#{ENV['ORGNAME']}"
  syntax_check_cache_path  "#{ENV['HOME']}/.chef/syntax_check_cache"
  cookbook_path            ["#{current_dir}/../cookbooks"]
  cookbook_copyright "Your Company, Inc."
  cookbook_license "apachev2"
  cookbook_email "cookbooks@yourcompany.com"

  # Amazon AWS
  knife[:aws_access_key_id] = ENV['AWS_ACCESS_KEY_ID']
  knife[:aws_secret_access_key] = ENV['AWS_SECRET_ACCESS_KEY']

  # Rackspace Cloud
  knife[:rackspace_api_username] = ENV['RACKSPACE_USERNAME']
  knife[:rackspace_api_key] = ENV['RACKSPACE_API_KEY']

Create the chef-repo

There are two ways to create a chef-repo when using the Chef boilerplate repository as a base:

  • Clone the chef-repo from GitHub
  • Download the chef-repo as a tar.gz file and place it into local version source control.

Note

Chef strongly recommends using some type of version control tool to manage the source code in the chef-repo. Chef uses git for everything, including for cookbooks. git and/or GitHub is not required to use Chef. If another version source control system is preferred over git (such as Subversion, Mercurial, or Bazaar) that is just fine.

Clone

The chef-repo is available on GitHub: https://github.com/opscode/chef-repo.

To clone the chef-repo from GitHub:

  1. Download and install git.

  2. Run the following command:

    $ git clone git://github.com/opscode/chef-repo.git
    
  3. (Optional) After the chef-repo is cloned, the history of that repository can be wiped out by removing the ”.git” directory, which allows the initialization of a new repository or to move the chef-repo into another version source control system, such as Subversion, Mercurial, or Bazaar.

Download

Instead of cloning the chef-repo from GitHub, a tar.gz file can be downloaded from GitHub directly (http://github.com/opscode/chef-repo/tarball/master) or through the command shell using GNU Wget (or a similar application).

To download the chef-repo:

  1. Run the following command:

    $ wget http://github.com/opscode/chef-repo/tarball/master
    
  2. Extract the tar.gz file into a directory. For example:

    $ tar -zxf master
    
  3. Move the extracted file to the chef-repo. For example:

    $ mv opscode-chef-repo-a3bec38 chef-repo