Since Chef 0.10.10, there’s been a new core resource for installing Ruby gems to support Chef cookbooks: chef_gem. This installs gems into the current Ruby at compile time, and handles making the newly-installed gems available to the running Chef client – wrapping up an ugly piece of code found in many cookbooks:
1 2 3 4 5
into a single resource declaration:
We hadn’t considered switching to this resource though, despite a compatibility cookbook being available for older Chef versions, because our local Ruby environment is based on RPMs. We build a single Ruby RPM for all our management tools, with individual gems also built into RPMs, so our gem dependency resources specify yum_package rather than gem_package.
This hasn’t given us any problems beyond a need to patch cookbooks to install our RPMs, but now we’re open sourcing some of our cookbooks, it means that our dependencies are specific to our local environment.
Using chef_gem as an abstraction though, we can specify dependencies in a way that’s appropriate for an open source cookbook but have a local override which actually installs our RPMs. We also avoid having to patch cookbooks just to make sure our RPMs are installed for dependencies.
This is the resource definition, which is a shim between the chef_gem resource and the yum_package provider, adjusting the requested package name as we need for our RPMs.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
This code goes in a local-enviroment cookbook as a library. Once we upgrade to Chef 0.10.10 or later, it will override the core chef_gem resource, and continue to install our RPMs.