I’ve been doing a lot of work with Chef and Berkshelf over the last few years. I started in a world without Berkshelf and wrote a conglomeration of spaghetti cookbooks that had a mess of dependencies and were very difficult to maintain. Eventually, I bit the bullet and started using Berkshelf 2.0 to manage my dependencies for cookbooks across many Chef servers and cookbooks and my life got better. However, people often ask me “What is Berkshelf and why should I use it?” If you read the Berkshelf pages, it certainly sounds simple enough, but when you sit down and actually use it, there’s often a bit of a conceptual hump you need to get over.
Berkshelf’s primary value (to me) is to go out and fetch any dependent cookbooks that you need to use in your cookbook(s), then upload them to the Chef server when you are ready to use them.
In a non-Berkshelf world, if you want to use recipes or resources from cookbook “abc”, you might need to do the following steps:
- Add
depends ‘abc’
to your metadata.rb file - Add
include_recipe “abc::default”
in one of your recipes. - $
git clone ssh://github.com/repos/abc.git
- $
knife cookbook upload abc
- Run
knife cookbook upload my_cookbook
- Run your cookbook on your nodes
. Repeat for any dependencies of abc
. Repeat for any dependencies of abc
Any time ‘abc.git’ is updated, you need to make sure you re-pull a new copy of it, the re-upload it back to the chef server. You need to be dilligent about checking periodically to know whether it’s been updated or not. This is easy if you only have one or two dependencies, but gets VERY painful if you have many dependencies. Furthermore, if abc has other dependencies, you need to chase all those down and upload them as well.
In the Berkshelf world, you let Berkshelf do the repetitive heavy lifting for you. You do the following:
- (same) Add
depends ‘abc’
to your metadata.rb file - (same) Add
include_recipe “abc::default”
in one of your recipes. - Add
cookbook ‘abc’ git:ssh://github.com/repos/abc.git’
to a new Berksfile 1 - Run
berks install
to make Berkshelf fetch your new abc.git cookbook (and as many other dependencies as you need) - Run
berks upload
to upload your cookbooks (including abc) to the Chef server - (same) Run your cookbook on your nodes
(Note: I’m assuming you’ve at least attempted to read the berkshelf.com intro pages and installed Berkshelf, then run ‘berks init’ on your cookbook.)
At first glance, this seems almost as complicated as the non-Berkshelf world. If you have zero or one dependency, then you are probably right. However, if you have more than one dependency, or if abc depends on other cookbooks out in the world, then your life gets suddenly MUCH easier. Not only does Berkshelf fetch the cookbooks that you specified, but it fetches all the other cookbooks in the world that THOSE cookbooks depend upon and uploads them properly. For Chef Continuous Integration and publishing of cookbooks on a regular basis, we do the same thing for all cookbooks that we monitor: berks install, berks upload. That’s it. Simple, and effective.
1 FOOTNOTE: If the abc cookbook lives in a “commonly known” location (e.g., the Opscode Chef community marketplace servers), you don’t need to add anything to the default Berksfile. Berkshelf will automatically go look in those known places based on simple references in your metadata.rb file.