Skip to end of metadata
Go to start of metadata



Cookbook Development Workflow for Chef Cookbooks

This page describes development workflow for Chef cookbooks using Git as the version control system.


It is not a comprehensive guide to Git, to learn more about Git itself:

This page will walk through five examples:

  • Building a new cookbook and saving it to the local repository.
  • Downloading an existing cookbook from the Chef Community Site.
  • Modifying an existing cookbook in the local repository for new updates.
  • Using Version Control to check the last change made to the local repository.
  • Adding a remote repository url to the git directory so you can push the commits to your own remote git repo.

Pre-requisites

The user should already have cloned the skeleton Chef Repository from Opscode's GitHub repository.

git clone Opscode's chef-repo skeleton

The remaining examples will be done from the chef-repo directory.

Work from chef-repo

As this is already a git repository, it's already set up for you to use with Git. However, the remote origin is still Opscode's repository. See the remote repositories section of this article for information on remote repositories in Git.




This book has been built by dozens of people in the Git community, and is meant to help you learn how to use Git as quickly and easily as possible.

New Cookbook

A cookbook is a directory which contains the recipes and supporting code and assets. Create a new cookbook with knife.

knife cookbook create working_with_git

This will create a predefined directory structure of all the various components of a Cookbook.

Pre-filled contents are configurable
The contents of the README and metadata are configurable. See knife cookbook create --help.

As it has created files, the git working copy will have uncommitted changes.

Show that we have uncommitted changes

Here's what the cookbook directory contains:

Contents of the cookbook's directory
Why all those directories?
Are all those directories required? No, they are not.

Why do we create all those directories? Simply because we don't know what you want in your cookbook. It is safe to leave them there, or delete the ones you don't need.

For this example, we'll just leave them there.

Next, let's edit the default recipe to do something.

vi cookbooks/working_with_git/recipes/default.rb

Now write the changes to the git repository. This is done in two steps. First, we add a list of files with git-add.

Tell git what files will be committed

We can view the changes that will be written with git-status.

Show what will be committed

Next use git-commit to write the changes to the repository.

Write the commit (changes) to the repository


Congratulations!

You've created a cookbook and written the changes to the local git repository.
To use the cookbook depends on whether you're using Chef Solo or Chef client with a server.

What is metadata.json?

If you are using a Chef Server, after doing the knife cookbook upload, you might notice there's a new file, metadata.json, in the cookbook.

Show generated metadata.json file

This is the generated JSON file from the upload. This is dynamically generated, and if you modify the metadata.rb, it will change every time the cookbook is uploaded. You can add metadata.json to the .gitignore file to ignore these generated files, but make sure to always use the metadata.rb file for modifying the cookbook's metadata.

Use .gitignore to ignore metadata.json files

Notice that we only added the .gitignore file, the metadata.json file is still there, Git just won't show it as uncommitted anymore.

Read more about cookbook Metadata. Read more about gitignore(5)

Download Cookbook

Opscode provides a centralized location for the Chef Community to share and download cookbooks. Knife can be used to retrieve cookbooks from the Community site and automatically integrate them into the local Git repository.

Make sure that the local repository has all changes committed:

Use Git Status to show clean repository

For this example we're going to download the chef-client cookbook and integrate it into the local repository using the "vendor branch" pattern. Output of filenames in the cookbook are truncated; you can view the full output by running the same command.

knife cookbook site install chef-client

This command does the following:

  • Download the cookbook tarball from cookbooks.opscode.com.
  • Ensure its on the git master branch.
  • Checks for an existing vendor branch, and creates if it doesn't.
  • Checks out the vendor branch (chef-vendor-COOKBOOK).
  • Removes the existing (old) version.
  • Untars the cookbook tarball it downloaded in the first step.
  • Adds the cookbook files to the git index and commits.
  • Creates a tag for the version downloaded.
  • Checks out the master branch again.
  • Merges the cookbook into master.

By default, the cookbook's dependencies are also downloaded. The -D option can be used to prohibit dependency download. Learn more about cookbook dependencies.

Specify an "Integration" branch
An integration branch is the one that the cookbook gets merged into to integrate it into the repository. By default, this command uses "master" as the integration branch. If you have Chef 0.9.14 or higher, you can specify a different branch with B BRANCH or -branch BRANCH.

We can now view some changes from this command in the repository. First, a new git-branch(1) is created:

git branch

The "*" in front of master indicates it is the currently checked out branch.

Also, a git-tag(1) is created:

git tag

Modify Cookbook

After you have created a new cookbook, or installed a cookbook in the repository with the install command, you may want to make modifications. Edit the files as desired and commit your changes to the Git repository. The filenames and contents changed are not important. Assuming we've editted a recipe and saved changes to the file:

Edit files and save changes
git status to show uncommitted changes
git diff to see file content changes

Add the file to the commit and create the commit.

git add, git commit

Tracking Upstream Changes

One advantage of using the vendor branch pattern described above is it becomes easy to make local changes to a cookbook, and still be able to retrieve upstream improvements and other changes. Once your local changes are committed, you can download a new version again with the same command.

knife cookbook site install

Note: there weren't any updates, since we had just downloaded the cookbook of the same version already. If we did make changes and there were updates on the Community Site, then they would be merged in.

If there are any conflicts between local changes and the upstream's update, then we would handle those by editing the files, or modifying the local copy in the repository. Read more about branching and merging, "Resolving a Merge" section of the online Git Community Book.

Version Tracking

All git repos have version tracking, so even if you are just committing changes locally you can still go back and see what was changed.

You can use git log to see the log of commits. This command would show you the last 3 commits for example:

git log

You could then see more information on a specific commit with git show. For example, to see more information on the last commit you could take the commit id and use it in this command:

git show

For more information on the show and log commands, reference the git-show and git-log manual pages. The command `man gittutorial` can also give you further information on how these can be used.

Testing Cookbooks

Testing cookbooks is not directly related to Git, but depending on how you're using Chef determines what you need to do to test changes you've made to cookbooks.

If you're using Chef Solo

You'll need to copy the cookbooks you want to use to a system with Chef Solo, configured to use the cookbooks directory. You'll also need to pass a JSON file to chef-solo with the run_list of recipes to use. See the Chef Solo page for information about how to set up a system to run chef-solo.

If you're using Chef Client/Server

Upload the cookbook to the Chef Server with Knife:

knife cookbook upload

Then apply the recipe to a node or role and run Chef on the desired system.

Remote Repositories

By default, the remote origin is Opscode's repository. This means that you can make commits to the local repo for version tracking and other features, but not the remote repo so you can access externally.

If you would like to add a remote origin for your personal git, you will first want to add a new repo to your git server. Once that is done you can add the remote origin with a command like this:

git remote

Then, whenever you want to push commits to your remote git you can do it with this command, after using git add and git commit:

git push to remote

You can use any name in place of github in these examples, it is just a name for the remote connection. For more information on remote, read the git-remote manual page.

Here's an example of how your workflow may look, once this is all setup:

1. Create the cookbook directory skeleton with knife cookbook create.
2. Edit the files you want to modify in the new cookbook or an existing cookbook.
3. Upload the cookbook to the Chef Server with knife cookbook upload.
4. Test that the cookbook changes you made work by running chef-client.
5. Stage the files to commit to your local repository with git add <filepattern>.
6. Commit changes to the repository with git commit.
7. Push commits to the central git server repository with `git push <remotename> <branchname>`.

Keep in mind that due to how git actually works, we can't predict what the proper behavior for #5 and #6 will be.





Labels:
None
Enter labels to add to this page:
Please wait 
Looking for a label? Just start typing.