Skip to content

Instantly share code, notes, and snippets.

@worace worace/
Created Jun 3, 2012

What would you like to do?
Chef Basic WalkThrough
# packages for a simple main recipe
package "git-core"
package "vim"
package "make"
package "curl"

###Preface The BlueBoxes are bare. Like, seriously silicon desert wasteland bare. You will probably need to install some very basic standard packages like curl, wget, make, etc. before you are even able to start using remote scripts to bootstrap your system. apt-get is your friend and will get you through these trying times. Don't forget to sudo.

###0a -- For Empty VPSes Bootstrap your system by installing Ruby 1.9.3 and installing Chef Per the point above, when you first come to your bare VPS there will probably not be a ruby version or a chef version installed. Fortunately the wizened nerds in the DevOps community have put together various scripts for "bootstrapping" this process. This one seemed to be a winner for the Ubuntu version running on our BlueBox VPSes (12.04): --> This part will take several minutes. Take a pomodoro. Down a quad espresso. GET AMPED FOR DEVOPS. After it is done, you should be able to run which ruby and which chef-solo and see some results. If you don't see anything, then something is awry.

###1. Set up a Chef Directory For working on Vagrant, it makes this to be in the same directory where your Vagrantfile lives; this way you will access it at /vagrant/chef when you are ssh'ed into your vagrant.

###2. Create a solo.rb and node.json in the top level of your chef directory solo.rb is the basic "run file" for your chef-solo, and node.json stores some attributes like the list of recipes to run.

For now, add these to solo.rb: cookbook_path File.expand_path("../cookbooks", __FILE__) json_attribs File.expand_path("../node.json", __FILE__)

###3. create a "main" cookbook to install some basic packages for starters Directory structure should look like this

 -- chef
  | -- solo.rb
  | -- node.json
  | -- cookbooks
     | -- main
        | -- recipes
           | -- default.rb

###4. Put some basic stuff in your recipe In default.rb add the line package "git-core" In node.json add { "run_list": ["recipe[main]"] }

This will tell your recipe to use the system's package manager to install git-core, and adding it to your run_list will tell chef to run this recipe.

###5. Install some cookbooks using Knife, Chef's built-in cli Knife is sort of like rubygems for pulling chef cookbooks from the web. By default it pulls the hosted repos from Opscode's community site, but with the knife-github-cookbooks plugin you can also pull from any git repository.

To get knife-github-cookbooks run: gem install knife-github-cookbooks

####5a. To use knife, you have to init a git repo in your chef directory. This is opscode's way of encouraging you to treat your chef repos as source code, which is probably a good idea. Once you have a lot of stuff in here you will want to have it backed up, and getting it on github will make it easier to share with your team.

####5b. Let's try using knife to install a cookbook -- this may get hairy From your chef directory (hopefully in the same directory as your Vagrantfile, if you're following along in vagrant mode), try running: knife cookbook site install nginx --cookbook-path ./cookbooks With any luck, you'll get the nginx recipe copied down and can add it to your runlist in node.json It will look like this: { "run_list": ["recipe[main]", "recipe[nginx]" }

"run_list": ["recipe[vagrant]"]
root = File.absolute_path(File.dirname(__FILE__))
file_cache_path root
cookbook_path root + '/cookbooks'
json_attribs root + '/node.json'

#This Tutorial Will Walk You Through the Steps of Making a Basic Chef Repo for Vagrant

We will assume that you already have vagrant and virtualbox set up on your local machine, along with a 1.9+ install of Ruby and the Chef Gem. If your system doesn't have these installed yet, you can get started with a "bootstrap" script like this one:

  1. Make a directory for your vagrant (this could be in a project directory but to keep things clean we will use a fresh directory). mkdir chef_vagrant_tutorial

  2. In this new directory, intialize your vagrant with vagrant init. We will be using a vagrant running Ubuntu Precise32 -- if you don't have a precise32 vagrant box you can add one with vagrant box add precise32

  3. Edit the line in your Vagrantfile to use the precise32 box: = "precise32"

  4. In the chef_vagrant_tutorial directory, make a chef directory to hold our nascent chef files.

  5. Create files called solo.rb and node.json in the top level of your chef directory. solo.rb is the basic "run file" for working with chef-solo, and the node.json file stores configuration variables that chef will use when run.

For now, add these to solo.rb: cookbook_path File.expand_path("../cookbooks", __FILE__) json_attribs File.expand_path("../node.json", __FILE__)

Working With Cookbooks

This gives us the basic structure for working with chef. Now we can get to the interesting part -- working with cookbooks.

  1. For starters, create a "vagrant" cookbook that we can use to install some basic packages and get a feel for how chef works. Each cookbook contains one or more "recipes," which are ruby files that tell chef what to do. For example, the MySQL cookbook might contain several recipes that are involved in getting MySQL installed -- one could install MySQL client and one could do MySQL server, etc. For our "vagrant" cookbook, let's make a simple recipe called default.rb to install some things! Set up your directory structure like this:

     -- chef_vagrant_tutorial
        -- Vagrantfile
        -- chef
         | -- solo.rb
         | -- node.json
         | -- cookbooks
            | -- vagrant
               | -- recipes
                  | -- default.rb

By convention, Chef will look for a recipe called default.rb if no other is specified, so it's common to just use this filename when making simple ones for yourself. Don't be surprised if you come across more complicated cookbooks in the wild that reference different recipe files.

  1. Recipes basically use a Ruby DSL to run commands on the system where chef is being run. The Chef DSL itself is pretty simple but Chef does some powerful things behind the scenes in order to make its commands system-agnostic and idempotent. For our purposes, lets get started with a very simple example, installing git. To do this, add the line:

package "git-core"

to default.rb in our "vagrant" cookbook. This will tell chef to use your system's package manager to install the package "git-core."

What's neat about this is that chef will automatically figure out what package manager to use, so we can count on it to pull up apt-get on Ubuntu or rpm on Fedora, etc. This makes our recipes OS-agnostic -- TRES MAGNIFIQUE!

  1. We have a basic recipe in place, but now we want to cook it up! To do this, we have to tell chef to run the recipe by adding it to the "run-list" in our node.json file. Add these lines to node.json:

        "run_list": ["recipe[vagrant]"]

With this structure in place, we are ready to run our recipe! Luckily the vagrant boxes come with Ruby and Chef installed, so we don't worry about bootstrapping the system.

Run vagrant up to start your vagrant and then vagrant ssh to ssh to it.

Vagrant Shared Directories

If you cd to /vagrant while ssh'ed into the vagrant box, you'll notice the chef directory we previously created is magically there! This is a handy feature of vagrant, which creates a virtual folder from your host machine to the vagrant box. Basically, any files or directories you place in the same directory as your Vagrantfile will be available when you ssh to the box.

Running the Recipe

Now you are ready to cook up your first Chef recipe! Before we start, try running git or which git on your vagrant box to verify that it is not installed. You should see no output or an error. Let's remedy that by running our recipe!

  1. Make sure you're in the chef directory with cd /vagrant/chef

  2. run the chef script with sudo chef-solo -c solo.rb

This will read the filepaths from solo.rb, pick up the run-list from node.json, and run the appropriate recipes! If all goes well, you should see some output from Chef to say

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.