Terry : Berkshelf


What is Berkshelf?

Berkshelf is a tool to manage a Cookbook or an Application's Cookbook dependencies. 

If you’re familiar with Bundler, then Berkshelf is a breeze.


Add Berkshelf to your repository's Gemfile

gem 'berkshelf' 

Or run it as a standalone

gem install berkshelf


Specify dependencies in a Berksfile in cookbook's root

site :opscode

cookbook 'mysql'
cookbook 'nginx', '~> 0.101.5'
# cookbook 'apt'
# cookbook 'yum'

A complex Berksfile from chef-solo-pattern

site :opscode

# Base Blocks
cookbook "ohai"
cookbook "openssl"
cookbook "database"
cookbook "rvm", git: "git://github.com/fnichol/chef-rvm.git"
cookbook "rvm_passenger", git: "git://github.com/fnichol/chef-rvm_passenger.git"

# Weird Blocks
cookbook "radar-console", path: "chef/custom_cookbooks/radar-console"

Install the cookbooks specified in the Berksfile and their dependencies

berks install

NOTE: the cookbooks will be installed ~/.berkshelf by default, it can be altered by setting environment variable BERKSHELF_PATH.

Add the Berksfile to the project

git add Berksfile
git commit -m 'add Berksfile to project'

A Berksfile.lock will also be created. Add this to version control if you want to ensure that other developers (or your build server) will use the same versions of all cookbook dependencies.

Berkshelf with Chef Solo

berks install installs the cookbooks into ~/.berkshelf/cookbooks which works well with a Chef Server. If running Chef Solo (tar the files and scp over using Capistrano), you'd better know that berkshelf has an option to vendor the cookbooks in Berksfile, ready to be packaged and distributed. See the following command

berks install --path chef/cookbooks

It installs all the downloaded cookbooks to chef/cookbooks, dependencies solved, ready for a chef solo run now!!!

NOTE: This help to reduce manual copying the downloaded cookbooks in ~/.berkshelf/cookbooks and renaming them to do a chef solo run.

Non Opscode Cookbooks

This works great for Opscode provided cookbooks, but what about other cookbooks you find on github? No problem - just provide a path to the git repository and Berkshelf will take care of things.

Base Blocks
cookbook "mysql", git: "https://github.com/opscode-cookbooks/mysql.git"

# specify a branch or tag
cookbook "mysql", git: "https://github.com/opscode-cookbooks/mysql.git", branch: "1.0.1"

# use the new shorthand for repositories hosted on github
cookbook "artifact", github: "RiotGames/artifact-cookbook", ref: "0.9.8"
Weird block

All of the above makes it really easy to get those base blocks in place. But what about our weird blocks? Do they just get mixed in with all the other ones in chef/cookbooks that Berkshelf is managing for us?

We could leave them in chef/cookbooks, but if we move them somewhere else (say, chef/custom_cookbooks) we can .gitignore chef/cookbooks. We can have Berkshelf copy our weird blocks in by specifying them with a path in our Berksfile like this

cookbook 'radar-console', path: 'chef/custom_cookbooks'

Reference: http://spin.atomicobject.com/2013/01/03/berks-simplifying-chef-solo-cookbook-management-with-berkshelf/

Manage Existing Cookbook

If you already have a cookbook and it’s NOT managed by Berkshelf it’s easy to get up and running. Just locate the cookbook and initialize it.

berks init ~/devops/chef/my_cookbook

NOTE: similar to git init

Creating New Cookbook

Create a new cookbook for a new application or supporting application

# Create a new cookbook named my_cookbook
berks cookbook my_cookbook
      create  my_cookbook/files/default
      create  my_cookbook/templates/default
      create  my_cookbook/attributes
      create  my_cookbook/definitions
      create  my_cookbook/libraries
      create  my_cookbook/providers
      create  my_cookbook/recipes
      create  my_cookbook/resources
      create  my_cookbook/recipes/default.rb
      create  my_cookbook/metadata.rb
      create  my_cookbook/LICENSE
      create  my_cookbook/README.md
      create  my_cookbook/Berksfile
      create  my_cookbook/Thorfile
      create  my_cookbook/chefignore
      create  my_cookbook/.gitignore
         run  git init from "./my_cookbook"
      create  my_cookbook/Gemfile
      create  my_cookbook/Vagrantfile

# Directory tree structure
tree .
└── my_cookbook
    ├── attributes
    ├── Berksfile
    ├── chefignore
    ├── definitions
    ├── files
    │   └── default
    ├── Gemfile
    ├── libraries
    ├── LICENSE
    ├── metadata.rb
    ├── providers
    ├── README.md
    ├── recipes
    │   └── default.rb
    ├── resources
    ├── templates
    │   └── default
    ├── Thorfile
    └── Vagrantfile
11 directories, 9 file

Getting Help

Run berks help

$ berks help
  berks apply ENVIRONMENT     # Apply the cookbook version locks from Berksfile.lock to a Chef environment
  berks configure             # Create a new Berkshelf configuration file
  berks contingent COOKBOOK   # List all cookbooks that depend on the given cookbook
  berks cookbook NAME         # Create a skeleton for a new cookbook
  berks help [COMMAND]        # Describe available commands or one specific command
  berks init [PATH]           # Initialize Berkshelf in the given directory
  berks install               # Install the cookbooks specified in the Berksfile
  berks list                  # List all cookbooks (and dependencies) specified in the Berksfile
  berks outdated [COOKBOOKS]  # Show outdated cookbooks (from the community site)
  berks package [COOKBOOK]    # Package a cookbook (and dependencies) as a tarball
  berks shelf SUBCOMMAND      # Interact with the cookbook store
  berks show [COOKBOOK]       # Display name, author, copyright, and dependency information about a cookbook
  berks update [COOKBOOKS]    # Update the cookbooks (and dependencies) specified in the Berksfile
  berks upload [COOKBOOKS]    # Upload the cookbook specified in the Berksfile to the Chef Server
  berks version               # Display version and copyright information
  -c, [--config=PATH]    # Path to Berkshelf configuration to use.
  -F, [--format=FORMAT]  # Output format to use.
                         # Default: human
  -q, [--quiet]          # Silence all informational output.
  -d, [--debug]          # Output debug information

Get more detailed information about a command, or a sub command, ask it for help

$ berks shelf help
  berks shelf help [COMMAND]  # Describe subcommands or one specific subcommand
  berks shelf list            # List all cookbooks and their versions
  berks shelf show            # Display information about a cookbook in the Berkshelf shelf
  berks shelf uninstall       # Remove a cookbook from the Berkshelf shelf

The Berkshelf

Configuring Berkshelf

The Berksfile

Vagrant with Berkshelf


Enable the plugins in Vagrantfile 

Vagrant.configure("2") do |config|
 # vagrant-proxyconf
  config.proxy.http = "http://proxy.company.com:3128/"
  config.proxy.https = "http://proxy.company.com:3128/"
  config.proxy.no_proxy = "localhost,"
  config.berkshelf.enabled = true

The plugin will look in the current working directory for Berksfile by default. Just ensure that the Berksfile exists and when running vagrant up, vagrant provision, or vagrant destroy the Berkshelf integration will automatically kick in!

Setting a Berksfile location

By default, the Vagrant Berkshelf plugin will assume that the Vagrantfile is located in the same directory as a Berksfile. If your Berksfile is located in another directory you can override this behavior

Vagrant.configure("2") do |config|
  config.berkshelf.berksfile_path = "/path/to/Berksfile"

Sample Vagrantfile and Berksfile see => Gist



berkshelf @ GitHub