Rapid Configuration with Chef

Here’s the scenario: it’s 3:30 on Friday, and I’d like to spin up a new application server to sit in a linux cluster. Here’s what I have:

  • A provisioned, but completely empty VM

Here’s what I need:

  • A full install of Ubuntu Linux
  • Networking configured, because this will be an LVS client, this entails:
    • Setting up a primary static ip
    • Adding multiple IPs netmasked to on the loopback interface
    • Adding routing rules for those IPs
    • Disabling ARPing from those interfaces
    • Firewalling the box and allowing various services different levels of access
    • DNS setup
  • OpenSSH Server Installed
  • Apache Fully Configured, including:
    • PHP5 installed and configured
    • SSL Certificates Installed
    • Multiple Virtual Hosts setup
  • NFS setup, and appropriate shares mounted
  • NTP setup for clock synchronization
  • VMWare tools installed
  • A mail server enabled and configured to only accept mail from localhost, and relay through another machine on the network
  • Monitoring software installed and configured
  • Security software installed and configured
  • Memcached installed and enabled
  • An assortment of utilities for diagnosing load and network issues installed

I’d like to do all of this with the guaranteed consistency, so I do not want to do a single piece of it manually. So, let’s do it. I’ve got the Ubuntu install ISO mounted in the VM, I reboot, and add the following to the boot parameters:


Sit back and watch. 10 minutes later we have a full OS install with openssh server running, firewalled, and one user account added. Now, on my machine, I run one command:

knife bootstrap [SERVER] -x [USER] -P [PASSWORD] -r 'role[kw_server]' --sudo

It’s 3:50, and I’m done. Everything is installed, configured, and secured. Need to add a second or third server to the cluster? Rinse and repeat. The million dollar question: how on earth is this all possible? The answer: Chef. What is it? I’ll quote the creators (Opscode):

Chef is an open source systems integration framework built to bring the benefits of configuration management to your entire infrastructure. You write source code to describe how you want each part of your infrastructure to be built, then apply those descriptions to your servers. The result is a fully automated infrastructure: when a new server comes on line, the only thing you have to do is tell Chef what role it should play in your architecture.

I was able to accomplish automating system configuration through a combination of custom defined “roles”, and an assortment of “cookbooks” some downloaded and used as it, some tailored to my specific use, and some written from scratch. It is my goal over a series of posts to take you through the process of doing this yourself, attempting to address some of the problem areas I encountered while doing so, and some of the items that take a little longer to grasp. Of note, Chef is entirely written in ruby, and although I have very limited experience with the language thus far, the syntax is easy enough to understand that it shouldn’t frighten anyone off. There’s no advanced programming concepts, mostly what you’re doing is a putting together simple templates, and I did not see my lack of knowledge as a hinderance in any way.

The Nitty Gritty

Because I’d like these to be constructive, I’ll try to explain what every command does for the uninitiated:


Adding that line to the boot parameters on Ubuntu points the installed to what’s called a kickstart file. In the simplest terms, this is basically an answer file to all the questions the installer would ask you, as well as allowing you to do some minimal configuration and additional package installations. In my case, I’ve found the easiest way to configure a user account, partitioning, initial access, and the primary IP is to have a kickstart file define these things. Would it have been relatively easy to just set these things after installing the box? Yes. However, I think the most important/difficult part about going through this process is that you have to force yourself to do some extra work up front so that you never have to touch the actual server. The payoff down the line is well worth the time up front if you ever find yourself having to provision and deploy boxes at a rapid clip, you’ll want everything to happen automatically, with nothing waiting on your manual input. Initially I started with a very generic kickstart that would bring the box up via DHCP, but then I would have had to put properties on the node itself once chef was installed to configure networking, which didn’t seem ideal (too manual, even if it still didn’t involve touching the server). However, as I embraced the chef way of doing things, I found it was just as easy to create a dedicated kickstart file per-server automatically, and that actually lead to a better starting point for the box. I will go through all the details of creating this kickstart cookbook in part two when I introduce the concept of the cookbook.

knife bootstrap [SERVER] -x [USER] -P [PASSWORD] -r 'role[kw_server]' --sudo

Knife is the command line tool for chef, and you’ll find yourself using it quite regularly while working with chef’s cookbooks and recipes. In this case, however, we’re using the bootstrapping functionality of knife to completely configure our new server. What does the bootstrapping do? It logs onto the new box via SSH, installs ruby, ruby gems and chef itself. It configures chef on that box and registers it as a client to your server (in my case, I’m using the free server provided by Opscode). Finally, it can assign a role to the box. In our case, we’re assigning the “kw_server” role which is a collection of all the recipes and configuration needed to turn our box from a base OS install, to a fully configured application server. We’ll go through how the role system works in a later post as well.

Thus concludes my intro. If you’d like to see any of this in action (and you work with me) let me know and I’d be glad to run through it with you. As well, my goal is to get a series of posts written as sort of a road map for starting to use Chef at Wharton. Finally, I intend open-source the cookbooks I’ve written once I make them a little more cross platform, and make sure they’re general purpose / configurable enough to benefit other users.

7 thoughts on “Rapid Configuration with Chef

  • Hi Lew,
    I myself is a big fan of chef. But i’m a bit struck over the use of chef-server client model. I’m using chef-solo for installing vcap on my machine which is described over here(http://support.cloudfoundry.com/entries/20407923-single-multi-node-vcap-deployment-using-chef). But the problem with this is that the cookbooks and other required files have to be kept in the VM before starting the installation. For this reason my organisation decided to move to chef-server-client model. I was able to setup a dedicated chef server and connect clients to it. But i’m facing problems while using the available scripts for vcap setup using chef server-client model. If you have worked on a similar problem before please share your thoughts about it.


  • Hi Lewis,
    Great couple of posts about chef !
    Could you share some more details on your kickstart setup ? Do you generate the kickstart files from chef ?

    • Thanks! Although with Chef 11 out now in additional to a lot more best practices and patterns emerging, they’re starting to get a little dated! At the time I did use a chef box to create the kickstart files. Now we use VMWare templates and the knife vSphere plugin.

      • Oops didn’t see your reply. Yeah it’s a bit confusing to see different approaches as it’s evolving rapidly.

        Wouldn’t mind seeing a post about VMWare with knife, that’s the setup I have here 🙂

  • I can’t find any examples online of a kickstart script that installs Chef. I know how to make a kickstart script install packages (RPMs, in my case), but I’m not sure how to set things up such that Chef is/gets installed as a ruby gem. Can you share those parts of your kickstart?

Leave a Reply