Setting up a chef development environment (MacOSx)

In this tutorial, we’re going to setup these tools to be able to easily setup Chef recipes locally:

  • Cask, a brew plugin that helps to manage installed packages
  • Virtual box, to bootstrap virtual machines
  • Vagrant (and vagrant manager) to bootstrap virtualboxes in a command
  • Chef dk, to create chef project
  • Vagrant plugins: berkshelf, omnibus, guestadditions

Installing cask

Once you’ve installed brew, it’s easy to install this plugin, just shell

brew install caskroom/cask/brew-cask

We’ll now be able to easily install our chef dependencies.


Let’s install Virtualbox, Vagrant and ChefDK:

brew cask install virtualbox
brew cask install vagrant
brew cask install vagrant-manager
brew cask install chefdk
vagrant plugin install vagrant-vbguest
vagrant plugin install vagrant-omnibus
vagrant plugin install vagrant-berkshelf

As chef comes with its own ruby, we’ve to modify our PATH and Gem env to reference it.
So get the result of the ‘chef shell-init bash’ and paste it in your ~/.bash_profile file (you can change the PATH variable to [everything chef related]:$PATH

Chef-server setup

We’re now going to set up a mock chef server with chef-zero that will be used by Vagrant machines to provision databags.

knife cookbook create zero-env

Then adding a .chef/knife.rb file to put our chef-zero configuration

log_level                :debug
log_location             STDOUT
chef_repo = File.join(File.dirname(__FILE__), "..")
chef_server_url ""
node_name       "osgiliath"
client_key      "./chef-zero.pem"
validation_client_name   "validator"
validation_key          "./chef-zero.pem"
cookbook_path   "#{chef_repo}/cookbooks"
cache_type      "BasicFile"
cache_options   :path => "#{chef_repo}/checksums"

You also have to create a mock certificate (chef-zero.pem) containing any valid certificate data.

Project setup

In an other folder than the one of the serevr, we’re going to create a cookbook using chef-dk:

chef generate cookbook mycookbook
cd mycookbook
chef generate attribute
chef generate attribute . default
chef generate lwrp . default

Then code our infrastructure.
I our cookbook have some dependencies to other one, we’ll reference them in our berksfile

Finally, we would add a Vagrant file in order to bootstrap our recipe, using our chef zero environment in order to provide environment specific attributes:

# -*- mode: ruby -*-
# vi: set ft=ruby :
Vagrant.require_version '>= 1.5.0'
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
 config.omnibus.chef_version = 'latest' = 'chef/fedora-19' :private_network, type: 'dhcp'
  config.berkshelf.enabled = true
    zero_path = "../myzeroserverpath/"
  config.vm.provision :chef_zero do |chef|
    chef.cookbooks_path = zero_path + "cookbooks"
    chef.data_bags_path = zero_path + "data_bags"
    chef.environments_path = zero_path + "environments"
    chef.roles_path = zero_path + "roles"
    chef.run_list = [

Then just ‘vagrant init’ and ‘vagrant up’ to have our cookbooked VM started

Share Button

Leave a Reply

Your email address will not be published. Required fields are marked *