The Spice Kaffein must flow

Chef tooling in 2019

Dive into and map out the state of the art of Chef supportig tooling together to understand how they all fit together.

Apr 13, 2019
Updated Feb 2, 2025
💡 Updated to fix a typo and move external links into the content and off of the section headers.

So chef has been around for a while (almost 10 years!) and both the cookbook development flow as well as the tooling have changed over the years. While I don’t know the full history of everything and don’t claim to even know the best tools to use in any particular way, here are some of the chef ecosystem tools that I’ve recently used along with a couple that I haven’t.

Helpful bits that I have used

Vagrant

While not strictly related to Chef, Vagrant is basically a VirtualBox wrapper that lets you define local VM configurations and backing base VMs (called “boxes”) to automate bringing up local development environments. In this context I generally spin up a new Vagrant VM for each application or cookbook that I’m working on to provide a “clean room” environment and ensure I’m using the newest Chef development tools.

Part of the reason that this works so well is that the cookbooks I am writing actually live on the host machine and are mounted in the guest using shared folders. So destroying or reconfiguring the development VM is trivial and doesn’t affect any cookbooks.

ChefDK

The ChefDK is an installation package that contains everything needed to start writing Chef code.

Seriously, everything, including almost all of the tools listed in this article and a few that aren’t. Straight up the dopest of the opest, or it was until Chef-workstation came along (we’ll get to that in a minute).

Chef-client

The Chef client is agent installed on the server endpoint that checks into the Chef server and does the actual work of applying the Chef cookbook code.

Chef-server

The Chef server Stores all the configuration data for your environment, including cookbooks to be applied on nodes, metadata about nodes, databags, roles, environment files, and policyfiles.

If a Chef client is the worker, the Chef server is the executive staff that organizes everything.

Knife

Part of ChefDK, knife is the CLI tool that you will use to generally interact with a production Chef server, databags and chef clients. Specifically, knife is what you will use to get your cookbooks onto an actual Chef server and generate databags.

Chef executable

Another part of the ChefDK, the Chef executable is what you use to generate cookbooks, recipes, templates, etc. as well as install gems into the ChefDK environment.

It’s kind of funny becuase I never really thought of the Chef executable as separate tool, I just thought it was part of the Chef client that was just there after I installed the ChefDK. But it is quite helpful in generating new cookbooks and recipes, automatically creating unit and integration tests along with the recipes according to the generator templates I have configured.

Chef-shell

Chef shell is a CLI tool that starts an interactive ruby session with all the gems and environment settings that a Chef client would have when running. Super helpful for debugging recipes or when you’re trying to understand specific behavior of ruby objects or node attributes that would be available during a Chef client run.

Berkshelf

Berkshelf is basically a cookbook depnedency manager. When you are writing a cookbook you will state the first-level dependent cookbooks (and sometimes specific versions) in the cookbook metadata.rb file, but it is still your responsibility to retrieve those dependency cookbooks and move them around both when you are running your tests as well as when it is time to apply your cookbook to production nodes.

With Berkshelf you define the upstream source of a cookbook dependency (a git URL, Chef server, file path, private supermarket, etc.) and add in the public Chef supermarket as a generic catch-all, and Berkshelf retrieves those statically defined dependencies for you. Then it actually also retrieves those dependencies’ dependencies and just generally makes your life a whole lot easier.

Cookstyle

Cookstyle is a Chef-specific static code linter based on rubocop. Great for quickly spotting broken code from typos and helping to follow style best practices.

Since it’s based on rubocop, Cookstyle can generate the same .rubocop_todo.yml file to help you incrementally work through your style warnings, or even use it as a whitelist for style “violations” that actually need to remain in your recipes. Cookstyle can even autocorrect some detected warnings, for extra efficiency.

After I make a change to a recipe I usually verify its validity and behavior using the following chain: Cookstyle > Foodcritic > Chefspec > Inspec (via Test Kitchen).

Foodcritic

Foodcritic is another Chef-specific static linter, but with a slightly different focus from Cookstyle. While Cookstyle is focused on the validity of the content of the code in your cookbooks, Foodcritic is focused on the structure of your cookbooks as individual entities and how portable they are across the Chef community.

Foodcritic checks cookbooks for things like valid license terms, updated READMEs, valid metadata.rb files, etc.

Chefspec

Chefspec is a Chef-specific extention of the RSpec testing framework. It’s super cool because it simulates a Chef client (and, depending on how you configure it, server too!) in memory to verify the behavior of your cookbooks.

This is instrumental in helping me verify both that my Chef code isn’t broken as well as that it does what I think it does. Since it’s running in memory it only takes a few seconds to run and gives me some quick feedback.

As an added bonus, if you write your tests right you can use the pseudo-English language tests as a shorthand when you’re revisiting old cookbooks and trying to remember what they do and how they work!

Inspec

In the context of writing Chef cookbooks, Inspec is a test framework that inspects the actual state of an actual machine and verifies that the state matches the pseudo-English language tests that you wrote. While Chefspec tests what the Chef code should do (“use the package resource to install the vim application from yum repos”), Inspec verifies the state of a machine and reports what your Chef code did do (“is vim installed”).

This is a subtle but important difference, and is actually why Chef (the company) advertises Inspec as a general purpose auditing framework regardless if you use Chef or not.

Test Kitchen

Test Kitchen is an integration test framework that helps to automate instantiating instances (VMs or containers), apply your cookbook(s), and run integration tests to verify end-state behavior of those instances. This seriously increases confidence in your cookbook code since you’re actually applying it and reporting on an instance’s end-state.

I use the kitchen-docker driver to quickly generate docker instances (using images from the excellent Bento project), provision the instance with development cookbooks, and then verify the state of the instance using Inspec.

Now maybe you’re asking “Why not just use Test Kitchen and Inspec to verify your cookbooks and skip the whole Chefspec thing?”. And honestly I did at first because writing unit tests is a pain. But even though Test Kitchen only takes a minute or two to provision a docker container with a Chef client and then apply my cookbooks and run Inspec reports, after doing it a few times it sunk in how much longer 1-2 minutes is than the few seconds it takes Chefspec to run. And that extra overhead time started to add up.

Chef Zero (aka “Local Mode”)

Chef Zero is a lightweight Chef server that runs in-memory on a local machine. It used to be its own standalone tool but was folded into the Chef client as a feature. Chef Zero is not meant to be scalable or as a replacement for a real Chef server, but I’ve found that it can be useful for satellite deployments where you might not have a Chef server deployed but still need to apply cookbooks with environment files and databags.

There is also this other thing called Chef Solo and it’s kind of confusing trying to figure out the difference between Chef Zero and Chef Solo. But basically it boils down to that Chef Solo is deprecated and any reference to Chef Solo in the docs is actually Chef client local mode which is Chef Zero.

Ohai

Ohai is a helper tool that profiles the system it runs on and provides that collection of system data to the Chef client as “automatic” level attributes. Ohai is what lets you write logic in your cookbooks that lets you, for example, skip applying certain configurations if run on a docker guest but will be applied on a VM guest.

It’s actually pretty crazy the amount of system information that Ohai collects, so definitely take a look at the particulars of what is collected for your platform.

Parts that I haven’t used

And then there are a couple of tools that I haven’t had a chance to use yet, but wanted to mention as they look like they can definitely be useful in a Chef workflow.

Private Supermarket

The public Chef supermarket is a repository of publicly available cookbooks (similar to what the Docker Hub is for docker images). So it makes sense that a private supermarket is just a private version of the same thing installed on your servers behind your corporate firewall.

I guess setting one of these up could make sense if you don’t have a private git repo of some sort so you can’t manage retrieving cookbooks using Berkshelf. Or I guess if you want to internally define “officially” released cookbooks as ones that have been uploaded to the private supermarket. But you probably do have a git repository already, so why go through the extra work of setting up a private supermarket? Of course as soon as I write this, we’ll run into a scenario at work where this becomes necessary.

Stove

Closely related so supermarkets (both public and private), stove is a tool that helps upload a cookbook to any supermarket. Apparently that is a difficult enough process that warrants its own helper tool..?

Fieri

Likewise related to supermarkets, Fieri adds cookbook quality metrics to supermarkets.

Policyfiles

Admittedly I didn’t even know about policyfiles until they had already been out for a few years and when I first read about them I recall thinking “Oh schnap what the hell is this?”. Policyfiles are basically a way to statically define and version control the environment, role, cookbook version, and some cookbook data specific to each “service role” that you will apply to a node.

If you’ve ever had someone change a cookbook version or modify a role out from under you which directly affects some of your infrastructure, the function of policyfiles will immediately make sense to you. Unfortunately for me using policyfiles means a change in workflow and perspective, but one that I think should be more than a fair trade if it means I know exactly what is running where.

Chef-vault

A separate project started by Nordstrom and adopted by Chef, Chef-vault is a rubygem included in the Chef Client and Workstation that helps with providing node-specific access to encrypted databags.

Without Chef-vault, encrypted databags required managing keyfile separtae access and distribution or just distributing the same keyfile to every node (which kind of defeats the purpose of encrypting the data in the first place).

Chef workstation and chef-run

I’m actually really excited about using the new Chef workstation. A new introduction in 2018, Chef workstation is basically a superset of the ChefDK (that also technically deprecates the ChefDK) that also provides an ad-hoc SSH/WinRM based orchestration component, chef-run.

Push-based CM tools like Ansible can apply arbitrary or predefined code to an arbitrary selection of machines without preinstalling an agent, which is pretty awesome. Up until now a Chef workflow required either a bootstrap process that installs the Chef client or pairing something like Ansible and Chef together.

The addition of chef-run looks like it could streamline that initial deployment process and simplify those times when you need to control exactly when and where a cookbook runs. Although to be honest, I hope Ansible’s concept of rolling update batch sizes makes it into the chef-run options.

You may be saying “Hey, you don’t need Ansible or chef-run to do this, you can already do it using knife ssh!”. But you can’t, not really. Not without a functioning Chef server and an previously installed chef-client on the endpoint in question anyways. So this should make provisioning new servers, deploying applications, and generally managing server lifecycle much easier.

Parts that I’ve heard about but I think are deprecated

Push jobs

The opposite of traditional Chef client based pull-type jobs, push jobs are a Chef server side addon that lets the Chef server “push” commands and resources to clients in a similar fashion to how Ansible operates. Unfortunately in order to implement push jobs you need a functional Chef server in your environment, the Chef client, and the push jobs client installed on nodes.

I think there is also a limit around what commands can be sent to nodes. As in you can’t just send arbitrary commands, rather you have to associate the commands that can be run to a job, and then the discrete job unit to nodes. So it feels a little heavy handed when compared to other push-based CM tools, which is why I think that development has effectively been stopped.

Librarian

Looks like a pre-Berkshelf cookbook dependency manager.

Chef solo

I guess Chef solo is the original implementation of Chef product, before Chef server even existed. This implementation is fundamentally different than Chef Server + Chef client, or Chef Zero (which creates a local in-memory Chef Server) and requires special plugins to function with the rest of the Chef ecosystem and changing the way cookbooks are written. Since the “local mode” functionality has been entirely subsumed by Chef Zero the original Solo has been deprecated. Confusingly, Chef Zero “local mode” is still referred to as Chef Solo in the documentation.

Serverspec

Serverspec is an Rspec-based testing framework to verify the state of server infrastructure. While still an actively maintained project, as far as the Chef ecosystem is concerned it has been superseded by Chef InSpec. That being said, don’t write off Serverspec completely as it may fit your particular infrastructure compliance and testing use case.