Chef: A View from the Infrastructure Kitchen

Taken from my post at SendGrid.

Chef is something we use quite a bit here at SendGrid. If you’re not too familiar with it, Chef is an open source tool written in Ruby and created by Opscode that allows you to manage your infrastructure as code. Infrastructure as code? What does that mean? Well in this case infrastructure refers to servers (Chef calls these nodes), and code of course is the set of instructions developers write for computers to execute. Chef lets you design what your servers should look like in code, and then goes and builds them out for you. We use it for tasks such as deploying applications and updating our databases.

“Wow that sounds cool,” you say. Not only is it cool, but Chef has one of the best naming schemes I’ve seen. Tools like ‘knife’, ‘test-kitchen’, and ‘foodcritic’ are only the beginning. One of the core parts of Chef is the cookbook. A cookbook is essentially a specialized building block that gets used to build your node; each cookbook has it’s own purpose. Take the MySQL cookbook, it’s used whenever you need MySQL installed on a node. Inside the cookbook you’ll find recipes, which are specific tasks, for installing the server and client.

Diagram of basic Chef installation

Each node has a role, which is basically what type of server it is. Our role for a MySQL server would look something like this:

name “mysql_server”
description “A totally awesome MySQL server”
run_list “recipe[mysql::server]”

The first two parts are pretty self-explanatory. The run_list is the list of things that need to be ran on our node, in this case it is the server recipe from the mysql cookbook. What’s great is if you ever need more of this type of server, you just point Chef at the box and have it create more servers with the same role. You are also able to define attributes in your role or environment, similar to a role but usually represents a data center or location, that let you apply customizations such as what port to listen on.

Let’s look at a recipe now. A very basic recipe that will install git, a type of version management software, and create a file named ‘send’ in the ‘tmp’ directory with the contents of ‘grid’ and owned by Bob would look something like this:

package ‘git’ do
  action :install

file ‘/tmp/send’ do
  owner ‘Bob’
  content ‘grid’
  action :create_if_missing

Pretty straight forward, huh? One of the coolest things built into Chef, is support for templating files. For something like a database.yml (database configuration file) in a Rails app, the developer never needs to worry about anything other than what they use for development because Chef lets you easily overwrite the file during a deploy with the proper configurations.

When I first came to SendGrid, I knew very little about Chef. Now after working with it everyday, I think it’s an awesome tool that can fill a very necessary role in managing your infrastructure. Though we’ve had our ups and downs (some days there are lots of colorful words towards Chef), I would recommend it to everyone. It’s capable of much more than what I’ve explained here, so be sure to check it out!