Evolution in Cookbook Development at
What is Berkshelf?
● A Cookbook authoring productivity tool by
Jamie Windsor and the Riot Games crew.
● Replaces some functions of knife (cookbook
download / upload / create)
● A package manager of sorts (think bundler
● Simplifies collaborative development.
● Promotes wrapping and extending public
● Greatly simplifies cookbook and dependency
● Seamless vagrant integration. (via plugin)
“The Berkshelf Way”
1. Work in verticals from the outside in:
● Start with the application cookbook and work down through the
2. Favor Data-driven Cookbooks:
● Cookbook attributes preferred; tune on an environment level.
3. Write well-encapsulated Cookbooks:
● Stop using Roles. They aren’t immutably versioned and add additional
setup and complexity for users. Cookbooks should be self-contained.
4. Have short iteration loops:
● Use vagrant with berkshelf plugin to greatly reduce iteration cycle time.
● Think Gemfile; tells Berkshelf where it
should look for dependent cookbooks:
○ cookbook “nginx”, chef_api :config (Your chef server)
○ cookbook “nginx”, site :opscode (Opscode Public Cookbooks)
○ cookbook “nginx”, git: 'git://github.com/opscode-cookbooks/nginx.git'
○ cookbook “nginx”, path: '/Users/bob/cookbooks/nginx'
● You can tell Berkshelf to use your metadata
● Application, Wrapper, Utility Cookbooks
○ All explicitly namespaced.
● Cookbook metadata is the source of truth
○ depends statements in metadata.rb constrain
versions, not Berksfile.
● Chef Environments
○ Use of metadata makes production constraints much
○ Staging is unconstrained
■ Promotes faster iteration cycle
■ Reduces Ops overhead/bottleneck
○ For now, a placeholder that binds our base role with
an app cookbook.
# Check our hosted chef server first. Looks for the chef configuration
# info in ~/.berkshelf/config.json. If not there, run 'berks configure'.
# Now look at the community cookbooks.
# Finally, reference the metadata file in the cookbook.
maintainer "Fiksu Inc."
license "All rights reserved"
description "Installs/Configures Fiksu’s awesome app!"
long_description IO.read(File.join(File.dirname(__FILE__), 'README.md'))
depends "fiksu_nginx", "1.1.4"
depends "fiksu_redis", "1.2.3"
depends "monit", "0.0.15"
● All chef artifacts (cookbooks, roles, envs, etc.) in one
● Adding or extending public cookbooks was painful and
sloppy… git submodules were less than ideal.
● A very role-centric environment; tough to easily see the
“big picture” while working on a single cookbook.
● No use of Vagrant for testing. Everything was uploaded
to Hosted Chef and tested in EC2… cookbook testing in
isolation was impossible.
● One cookbook per repo.
● All Application Cookbooks use Berkshelf and Vagrant
for much faster iteration cycles.
● CI: Use TravisCI for linting (foodcritic) and syntax
checks (knife cookbook check).
● Little to no test coverage with chefspec/fauxhai or
● Still using roles.
● Well defined cookbook development workflow process
that empowers both dev and ops as productive
● Matured CI workflow (automated cookbook uploads to
● Embrace TDD in cookbook authoring is a must.
● Roles days numbered?