an old Australian cookbook There are many guides to writing a Chef cookbook.

But can you choose the right existing cookbook?

Let’s talk about how to choose, especially for Chef Solo, Chef Zero or MadScience.

Already know the basics? Skip ahead to how to choose.

Basic Terms: Attributes, Recipes, Data Bags, Resources and Providers

A cookbook is meant to install a piece of software. But you can usually configure that software in a lot of ways. You can use recipes, attributes and data bags to install in a fairly simple way, or you can write your own cookbook to call cookbooks based on LWRPs.

We’re going to focus strongly on recipes, attributes and data bags. If you preferred to write your own cookbook, you’d be reading a different online guide, right? Part of the point is to use somebody else’s.

Attributes are things like the version of the software, paths or URLs you need for install, and other configuration data. You normally set them with a JSON file on each Chef run, and you don’t normally expect their values to stick around.

Data Bags are similar, but you can write back to them. You can also use them to safely store encrypted data, though running serverless (like MadScience) allows you to achieve that result in a different way using SSH.

And again, we’re mostly going to ignore resources and providers. You can’t invoke them by setting attributes or data bags, so you’d need to write a cookbook. That’s not what this guide is about.

Popularity

First, you’ll want a feel for how popular and regularly-used the cookbook is. There are two places you should always check.

GitHub

Most cookbooks store their source code on GitHub. You can find it with a Google search. Make sure to pick the right one - it’s quite possible to have multiple cookbooks with the same name.

You can judge GitHub popularity in the usual ways: read the README. See how many stars or forks the cookbook has. See what issues have been opened and closed. Check pull requests, and how responsive the maintainers are.

The primary thing to do is make sure there’s at least some level of activity. If there’s a bug, do you want to have to fix it yourself? You may have to in some cases, but it’s great when you don’t.

The top banner of GitHub

Supermarket.chef.io

You can search Supermarket.Chef.io directly — or Google will normally find the cookbook on it anyway.

Supermarket has the same kind of activity statistics as GitHub, but with more Chef specifics. Is it a cookbook from the Chef company? That’s always a good sign. Or from reputable developers? Does it have a lot of downloads? A lot of followers or released versions?

Again, you’re mostly looking for a cookbook with some reasonable activity. And if you’re choosing between multiple and there’s no specific feature you need, you should normally choose the more active of the two.

If there is a specific feature you need, keep reading.

Here’s what those areas actually look like on a popular sample cookbook:

The top area of Supermarket.chef.io The side area of Supermarket.chef.io

Functionality

It’s great to choose by how popular a cookbook is, and by how well it’s maintained. But what if it doesn’t do what you want? How can you tell?

A great cookbook is well-documented. A good cookbook at least mentions the attributes and recipes, probably in the README. An okay cookbook is going to make you read through it, alas.

The README is available on the plugin’s top page on GitHub or Supermarket. So that’s normally the first thing you read.

Choosing Your Cookbook: Attributes

It’s useful to check the set of attributes.

In case you need to read the code: a cookbook generally has an “attributes” directory, and generally an attributes/default.rb file with a lot of lines like this:

default['mysql']['service_name'] = 'default'

# passwords
default['mysql']['server_root_password'] = 'ilikerandompasswords'
default['mysql']['server_debian_password'] = nil
default['mysql']['server_repl_password'] = nil

# used in grants.sql
default['mysql']['allow_remote_root'] = false
default['mysql']['remove_anonymous_users'] = true
default['mysql']['root_network_acl'] = nil

Each of those lines is setting up an attribute that the cookbook will potentially use later.

You can also look in the templates/default directory in the cookbook — that’s where configuration files are often kept, and those often substitute in values of attributes. There’s a files/default directory, but those files are normally used as-is rather than substituting.

You may also have some luck Googling for the cookbook by name. It’s especially useful to look for StackOverflow questions, which mean people having trouble. Or blog posts, which can be good or bad but usually have a lot more information.

The best, of course, are well-used cookbooks that people like.

Attribute docs from the Postgres cookbook

Choosing Your Cookbook: Recipes

As with attributes, it’s best if the README documents these directly. You can read the code, but it’s not a great sign if you have to.

The basic recipe with the same name as the cookbook is normally in recipes/default.rb. If you have a recipe called WhateverCookbook::Foo, it’s normally in recipes/foo.rb — in WhateverCookbook’s directory, of course, probably under “cookbooks”.

You can use a recipe from your runlist (see below), or you can use it from another cookbook via include_recipe.

Recipe docs from the Postgres cookbook

Choosing Your Cookbook: Data Bags

Data bag support was added to Chef Solo awhile back – or you can use them with Chef Zero or Chef Apply. They’re a lot like attributes, and are often stored in JSON files in exactly the same way.

Most of the recipes you want to use will be configured with attributes, not with data bags. But they’re basically similar, as long as you remember that they’re usually in separate JSON files.

Similarly, it’s best when data bags are documented in the README, but sometimes you need to check the code.

Cookbook code normally uses the search() function to check for databags by name. Which, of course, makes it very hard to grep for them using a distinctive name. That’s another reason to like them less than attributes.

Code using search() for databags from MySQL cookbook

Final Details: Running the Cookbook

If you have Chef Solo or Chef Zero set up, you’ll have a list of attributes and a runlist (set of cookbooks to run) set up somewhere, probably in a JSON file. If you’re running via Vagrant, these are “chef.json” and “chef.run_list” in the Chef provisioner.

For Chef with a server this is a bit more complicated, and you’ll need to use Knife invocations. See your docs for details.

In MadScience, check your nodes/app-server.json.erb file, which is both the data and the runlist. Add the recipe — the cookbook should be downloaded for you automatically without even changing the Cheffile.

If you’re not using MadScience, you’ll need to download the cookbook. You can do that in a Cheffile or Berksfile if you have one set up, or just download the cookbook itself and copy it to the appropriate directory, usually called “cookbooks”.