Creating a custom cookbook with Chef

Step 2: A simple cookbook with chef

You can find the files for this step in the following git hub repository:


Creating a custom cookbook with chef

Chef is used to describe the steps of the provisioning. This description comes from „cookbooks“ and these cookbooks contain recipes that describe the provisioning steps with ruby code.

So let’s start with a simple cookbook, that adds a user at the end of the provisioning just to get used to the structure of chef cookbooks.

First we need to download and install chef

vagrant plugin install vagrant-librarian-chef
vagrant plugin install vagrant-omnibus

Use chef a provisioner in Vagrant file and trigger recipe in custom cookbook

Then we need to adapt the Vagrantfile to use chef as provisioner and trigger our first recipe in our first custom cookbook.

# -*- mode: ruby -*-
# vi: set ft=ruby :

Vagrant.configure("2") do |config| = "trusty64"
  config.vm.box_url = "" :private_network, ip: ""

  config.vm.provision :chef_solo do |chef|
    chef.cookbooks_path = ["cookbooks","site-cookbooks"]

    chef.add_recipe "mycookbook"

As you see below, we specify a cookbook_path variable, with an array of directories. In our example we have:

  • cookbooks: Normally in this folder cookbooks are stored, that have a stable state. Most likely you get them from github or scm.

  • site-cookbooks: In this folder you can place cookbooks, that are under local development. Once you have finished them you can publish them and retrieve them in the same way as your normal cookbooks.


Technically chef is using a fallback here, cookbooks in the seconde folder have a higher priority as in the first folder. With 'chef.add_recipe "mycookbook"' we defince that "default.rb" in our cookbook ist the entry point for the provisioning process.

The anatomy of a chef cookbook

For our example we create the following file structure in our vagrant folder:

site-cookbooks (folder)
|--- mycookbook (folder)
     |--- metadata.rb (file)
     |---  recipes (folder)
          |---  default.rb (file)

Add metadata to your cookbook

This is the minimalistic example of a chef cookbook. To play arround, we add the following content to „metadata.rb“

name 'mycookbook'
description 'Just a simple test cookbook'
maintainer 'Timo Schmidt'
license 'none'
version '0.0.1'

Implement a simple recipe

We add the following content to the Chef recipe "repices/default.rb":

group "users" do
  gid 5000

user "testuser" do
  home "/home/testuser"
  gid 5000
  shell "/bin/bash“

Start the box and check the result of our first cookbook

Now we can create our box a usual with „vagrant up“. When the provisioning is done, we can log into the box (with „vagrant ssh“). Now check „/etc/shadow“ if our new user „testuser“ has been created.

vagrant ssh
cat /etc/shadow

With the blocks above you use „chef resource providers“. There are a lot of build in resource providers that help you to automize steps during the provisioning. You can find the documentation of the build in chef resources here:

As you can see chef provides very helpful „building blocks“ to configure your machine. In addition it is possible to implement these „resources providers“ in your own cookbooks and these concepts make chef very powerful.

We learned how to create an own cookbook and how to use recipes and resource providers, but to build a box it makes senses to use an combine other existing cookbooks. In the next step we will learn to use the apache cookbook to create a virtual host in our development system.

Click here to get to the next step, where we create a apache virtual host with our cookbook.