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
Or run it as a standalone
Specify dependencies in a Berksfile in cookbook's root
cookbook 'nginx', '~> 0.101.5'
# cookbook 'apt'
# cookbook 'yum'
A complex Berksfile from chef-solo-pattern
# Base Blocks
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
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.
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"
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'
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
run git init from "./my_cookbook"
# Directory tree structure
│ └── default
│ └── default.rb
│ └── default
11 directories, 9 file
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
Vagrant with Berkshelf
Enable the plugins in Vagrantfile
Vagrant.configure("2") do |config|
config.proxy.http = "http://proxy.company.com:3128/"
config.proxy.https = "http://proxy.company.com:3128/"
config.proxy.no_proxy = "localhost,127.0.0.1"
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