Jamie Winsor and a team of engineers created Berkshelf to help take the sting out of Chef’s learning curve. After encountering numerous challenges while developing Chef cookbooks, Jamie was inspired to create a tool based on criteria that’d be important for a developer’s productivity. Berkshelf, like Rebar, Go, or Mix, is a source code management tool.
11. WHAT’S
BERKSH
ELF?
‣ A COMMAND LINE
TOOL
‣ A SOURCE CODE
MANAGEMENT TOOL
▾ Similar to ‘Mix’, ‘Go’, or
‘Leiningen’
‣ A PACKAGE MANAGER
▾ Similar to ‘Gem’, ‘Apt’, or ‘Yum’
‣ REPLACES PORTIONS
OF KNIFE
▾ Cookbook Generator, Cookbook
Uploader, Cookbook Downloader
20. CREATE A NEW COOKBOOK
$ berks cookbook myface
create myface/files/default
create myface/templates/default
create myface/attributes
create myface/definitions
create myface/libraries
create myface/providers
create myface/recipes
create myface/resources
create myface/recipes/default.rb
create myface/metadata.rb
create myface/LICENSE
create myface/README.md
create myface/Berksfile
create myface/chefignore
create myface/.gitignore
run git init from "./myface"
create myface/Gemfile
create myface/Vagrantfile
Using myface (0.1.0) at path: '/Users/reset/code/riot-cookbooks/myface'
21. CONVERT AN EXISTING COOKBOOK
$ berks init
create Berksfile
create chefignore
create .gitignore
run git init from "."
create Gemfile
create Vagrantfile
Using old_cookbook (0.1.0) at path: '/Users/reset/code/riot-cookbooks/old_cookbook'
Successfully initialized
22. STUCK? ASK FOR HELP!
$ berks cookbook –h
Usage:
berks cookbook NAME
Options:
[--foodcritic] # Creates a Thorfile with Foodcritic support to lint test your cookbook
[--chef-minitest] # Creates chef-minitest support files and directories, adds minitest-handler …
[--scmversion] # Creates a Thorfile with SCMVersion support to manage versions for continuous
integration
-L, [--license=LICENSE] # License for cookbook (apachev2, gplv2, gplv3, mit, reserved)
# Default: reserved
-m, [--maintainer=MAINTAINER] # Name of cookbook maintainer
-e, [--maintainer-email=MAINTAINER_EMAIL] # Email address of cookbook maintainer
[--no-bundler] # Skips generation of a Gemfile and other Bundler specific support
[--skip-vagrant] # Skips adding a Vagrantfile and adding supporting gems to the Gemfile
[--skip-git] # Skips adding a .gitignore and running git init in the cookbook directory
-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
Create a skeleton for a new cookbook
28. METADATA IS IMPORTANT
COOKBO
OK
YUM
V1.2.3
SET WHAT COOKBOOKS YOU DEPEND ON
COOKBO
OK
CHEF-
SERVER
V1.2.3
COOKBO
OK
APT
V1.2.3
SUPPORTED
PLATFORMS
SUPPORTED
PLATFORMS
SUPPORTED
PLATFORMS
29. CHEF-SERVER COOKBOOK’S METADATA
name "chef-server"
maintainer "Opscode, Inc."
maintainer_email "cookbooks@opscode.com"
license "Apache 2.0"
description "Installs and configures Chef Server"
long_description IO.read(File.join(File.dirname(__FILE__), 'README.md'))
version "2.0.0"
depends "apt", ">= 1.7.0"
depends "yum", ">= 0.5.0"
%w{ ubuntu redhat centos fedora amazon scientific oracle }.each do |os|
supports os
end
30. IT STARTS WITH A BERKSFILE
"## Berksfile
"## CHANGELOG.md
"## CONTRIBUTING.md
"## Gemfile
"## LICENSE
"## README.md
"## Thorfile
"## Vagrantfile
"## attributes
$ &## default.rb
"## chefignore
"## libraries
$ "## dev_helper.rb
$ &## omnitruck_client.rb
"## metadata.rb
"## recipes
$ "## default.rb
$ &## dev.rb
&## templates
&## default
&## chef-server.rb.erb
Berksfile
site :opscode
metadata
group :dev do
cookbook 'git'
end
Berksfile
31. INSTALLING COOKBOOKS
Using chef-server (2.0.0) at path: '/Users/reset/code/riot-cookbooks/chef-server'
Installing git (2.5.0) from site: 'http://cookbooks.opscode.com/api/v1/cookbooks'
Installing apt (1.9.2) from site: 'http://cookbooks.opscode.com/api/v1/cookbooks'
Installing yum (2.2.0) from site: 'http://cookbooks.opscode.com/api/v1/cookbooks'
Installing dmg (1.1.0) from site: 'http://cookbooks.opscode.com/api/v1/cookbooks'
Installing build-essential (1.4.0) from site: 'http://cookbooks.opscode.com/api/v1/cookbooks'
Installing windows (1.8.8) from site: 'http://cookbooks.opscode.com/api/v1/cookbooks'
Installing chef_handler (1.1.4) from site: 'http://cookbooks.opscode.com/api/v1/cookbooks'
Installing runit (1.1.2) from site: 'http://cookbooks.opscode.com/api/v1/cookbooks'
$ berks install
33. UPLOADING COOKBOOKS
Using chef-server (2.0.0) at path: '/Users/reset/code/riot-cookbooks/chef-server'
Using git (2.2.0)
Using apt (1.9.0)
Using yum (2.1.0)
Using dmg (1.1.0)
Using build-essential (1.3.4)
Using windows (1.8.2)
Using chef_handler (1.1.4)
Using runit (0.16.2)
Uploading chef-server (2.0.0) to: 'https://api.opscode.com:443/organizations/vialstudios'
Uploading git (2.2.0) to: 'https://api.opscode.com:443/organizations/vialstudios'
Uploading apt (1.9.0) to: 'https://api.opscode.com:443/organizations/vialstudios'
Uploading yum (2.1.0) to: 'https://api.opscode.com:443/organizations/vialstudios'
Uploading dmg (1.1.0) to: 'https://api.opscode.com:443/organizations/vialstudios'
Uploading build-essential (1.3.4) to: 'https://api.opscode.com:443/organizations/vialstudios'
Uploading windows (1.8.2) to: 'https://api.opscode.com:443/organizations/vialstudios'
Uploading chef_handler (1.1.4) to: 'https://api.opscode.com:443/organizations/vialstudios'
Uploading runit (0.16.2) to: 'https://api.opscode.com:443/organizations/vialstudios'
$ berks upload
46. PUBLIC/PRIVATE RECIPES
PUBLIC RECIPE
‣ What you put in the
run_list of a node
‣ Documented in the
README
‣ Documented in the
metadata
PRIVATE RECIPE
‣ Not exposed to end user
‣ Should never be put in
the run_list of a node
‣ Always included into
other recipes
‣ Documented in the code
for other developers
50. TUNABLES OF MYFACE
1 listen on a different port or bind address
2 set memory usage of workers
3 any app config
4 set services to started or stopped states
51. 3 WAYS TO CONFIGURE
ATTRIBUTES
DATA BAGS
ENCRYPTED DATA BAGS
52. FAVOR CONFIGURING WITH ATTRIBUTES
‣ Path of least resistance for cookbook consumers
‣ Provide sensible defaults in the Attribute files
▾ Consider creating an attribute file for each recipe
‣ Can configure your application on an environment
level
53. WHEN TO USE DATA BAGS
USERS
GROUPS
YUM/APT
THINGS CONFIGURED BY "BASE"
COOKBOOK (IF YOU HAVE ONE)
ORGANIZATION LEVEL
CONFIGURATIONS
58. NOT VERSIONED
CAN’T BE PACKAGED / DISTRIBUTED
NOT NAMESPACED
STAHP USING ROLES
THEY ARE ORGANIZATION LEVEL DATA
ADDITIONAL SETUP COMPLEXITY FOR
THE USER
59.
60. USE DATA BAGS WHERE THEY MAKE
SENSE
DO YOU NEED TO STORE
ORGANIZATION-WIDE DATA?
DO YOU NEED TO STORE
SENSITIVE DATA?
Use one
Use an encrypted one
61. USE DATA BAGS WHERE THEY MAKE
SENSE
MOST IMPORTANTLY…
VALIDATE YOUR DATA
BAGS!
62. 5 include_recipe "myface::app_proxy"
6 include_recipe "myface::app_server"
7 include_recipe "myface::cache_server"
8 include_recipe "myface::worker_pool"
9 include_recipe "myface::database"
DEFAULTS RECIPE IS SPECIAL
65. LIBRARY COOKBOOKS
‣ Might have recipes, might not
‣ Contain LWRPs, Definitions, or Libraries useful to
other cookbook authors
‣ YUM Cookbook is a perfect example
▾ Contains a yum_key LWRP for adding repository keys to yum
▾ Contains a yum_repository LWRP for adding repositories to yum
▾ Contains some recipes to configure commonly used public yum
repositories on your machine
67. WRAPPER COOKBOOKS
‣ Super lightweight
‣ Contain recipes
‣ Contain attribute overrides
‣ Riot-Java is a perfect example
▾ Contains a Oracle Java 6 recipe
▾ Contains a Oracle Java 7 recipe
▾ An abstraction on top of the Java cookbook for Riot engineers
▾ Overrides the default “install flavor” for Java
▾ Overrides the default location of the Java artifacts to an internal
location
▾ NOT A FORK OF THE JAVA COOKBOOK
72. BERKSHELF VAGRANT PLUG-IN
$ vagrant plugin install vagrant-berkshelf
Installing the 'vagrant-berkshelf' plugin. This can take a few minutes...
Installed the plugin 'vagrant-berkshelf (1.2.0)'!
73. Bringing machine 'default' up with 'virtualbox' provider...
[Berkshelf] Updating Vagrant's berkshelf: '/Users/reset/.berkshelf/vagrant/berkshelf-20130424-40671-t43soz’
Generating chef JSON and uploading...
Running chef-solo...
[2013-04-25T03:01:31+00:00] INFO: *** Chef 10.14.2 ***
[2013-04-25T03:01:32+00:00] INFO: Setting the run_list to ["recipe[minitest-handler::default]", "recipe[myface::default]"] from JSON
[2013-04-25T03:01:32+00:00] INFO: Starting Chef Run for myface-berkshelf
#### CHEF RUN GOES HERE ####
[2013-04-25T03:02:10+00:00] INFO: Chef Run complete in 38.330025825 seconds
[2013-04-25T03:02:10+00:00] INFO: Running report handlers
Run options: -v --seed 41224
# Running tests:
minitesthandler::default#test_0001_runs_no_tests = 0.00 s = .
myface::default#test_0001_runs_no_tests_by_default =
0.00 s = .
Finished tests in 0.002425s, 824.7576 tests/s, 0.0000 assertions/s.
2 tests, 0 assertions, 0 failures, 0 errors, 0 skips
[2013-04-25T03:02:10+00:00] INFO: Report handlers complete
PROVISION NEW ENVIRONMENT IN
MINUTES
$ vagrant up
1 minute 20 secon
74.
75. Running chef-solo...
[2013-04-25T03:01:31+00:00] INFO: *** Chef 10.14.2 ***
[2013-04-25T03:01:32+00:00] INFO: Setting the run_list to ["recipe[minitest-handler::default]", "recipe[myface::default]"] from JSON
[2013-04-25T03:01:32+00:00] INFO: Starting Chef Run for myface-berkshelf
#### CHEF RUN GOES HERE ####
[2013-04-25T03:02:10+00:00] INFO: Chef Run complete in 0.520326234 seconds
[2013-04-25T03:02:10+00:00] INFO: Running report handlers
Run options: -v --seed 41224
# Running tests:
minitesthandler::default#test_0001_runs_no_tests = 0.00 s = .
myface::default#test_0001_runs_no_tests_by_default =
0.00 s = .
Finished tests in 0.002425s, 824.7576 tests/s, 0.0000 assertions/s.
2 tests, 0 assertions, 0 failures, 0 errors, 0 skips
[2013-04-25T03:02:10+00:00] INFO: Report handlers complete
CONVERGE IN SECONDS
$ vagrant provision
7 seconds