Managing Your Chef Gem Dependencies More Easily in your Gemfile

When writing Chef cookbooks, it's possible that we're going to want to use a gem as a dependency, for instance to interact with HashiCorp Vault using the vault gem.

To tell Chef that we want to have this gem installed before we perform a Chef run, we need to add it as a gem to our metadata.rb:

# other cookbook metadata

gem 'vault', '~> 0.16'

However, this then causes issues for us, as if we want to do any local testing, such as unit testing with ChefSpec, we can't rely on Chef to install these gems, as we're not really executing a full Chef run.

The solution, previously mentioned in my post about Chef's dependency management tools, is that we need to add this i.e. to our Gemfile, so Bundler can install the dependency:

source '...'

gem 'vault', '~> 0.16'

This then has the problem of our Gemfile and metadata.rb becoming misaligned, and can be quite annoying, as we may be testing against a different version than is installed by the cookbook. Fortunately, using the knowledge from my article Programatically Determining the Version of a Chef Cookbook, we can take advantage of the Gemfile being a Ruby file, and replace the Gemfile with:

source '...'

require 'chef'

m = Chef::Cookbook::Metadata.new
m.from_file 'metadata.rb'
m.gems.each do |name, version|
  gem name, version
end

This allows us to manage our Chef Gem dependencies for Chef and local development with Bundler, and remove the need to keep both updated!

An alternative would be to monkey patch Bundler::Dsl, but this also works as-is, and doesn't require anything else to be globally installed.

I've also raised this upstream with the Bundler team to see their thoughts about this being a first-class citizen.

Written by Jamie Tanna's profile image Jamie Tanna on , and last updated on .

Content for this article is shared under the terms of the Creative Commons Attribution Non Commercial Share Alike 4.0 International, and code is shared under the Apache License 2.0.

#blogumentation #chef #ruby.

This post was filed under articles.

Related Posts

Other posts you may be interested in:

Interactions with this post

Interactions with this post

Below you can find the interactions that this page has had using WebMention.

Have you written a response to this post? Let me know the URL:

Do you not have a website set up with WebMention capabilities? You can use Comment Parade.