There is lots of material on the Opscode site about how to use Chef in its various forms. The new Chef Quickstart Guide is a good place to start learning.  But this page is for people who are impatient, and just want to get on with it.  The assumptions are:

This HOW-TO, covers making simple changes to the recipes that Chef will run for your node.  As an example, we will add a new recipe to be run and specify the attributes that control it.

The structure of a node.json file

Lets start by looking at the "mynode.json" file:

  "name": "sample-chefsolo",
  "chef_environment": "_default",
  "setup": {
     "set_fqdn": "*"
  "run_list": [

First thing to note is that this file is a JSON file, and must conform strictly to the syntax for JSON.  (Syntax errors in the node JSON file will cause the chef-solo or chef-client to fail immediately.) For the remainder of this page, I'm going to assume that you understand what the JSON syntax is saying.

Look at the "runlist" attribute which defines the node's run-list.  Notice that its value is a JSON array of strings, with (in this case) one element.  The run-list describe the things that will be run by Chef for this node.  The elements can be either individual recipes (e.g. "recipe[...]") or roles(e.g. "role[...]").  The latter are essentially named lists of recipes that can be reused across multiple node run-lists.  In the above, we have specified the recipe as:


This specifies that the recipe named "default.rb" in the cookbook named "setup" is to be run.  If instead we have written


that would have specified that the recipe named "clamav.rb" in the "setup" cookbook should be run.  A complete list recipes to be run is formed by recursively "expanding" any roles into the run-list.  The recipes in the expanded run-list will be run in order, with the caveat that any given recipe will only be run once.

Now look at the "setup" attribute in the JSON above.

  "setup": {
     "set_fqdn": "*"

This shows how we can specify attributes to control or modify the behaviour of a recipe.  In this particular case, we are setting the "set_fqdn" attribute in the "setup" cookbook's namespace to the value "*".  (This example tells the "setup.rb" recipe to attempt to set the host's fully qualified domain name.  The value "*" means, set it to the DNS name obtained by doing a reverse lookup on the host's IP address.)

By convention, cookbook or recipe specific attribute names are organized into namespaces corresponding to cookbooks. Beyond that, the names and meanings of attributes are recipe dependant.  Check the cookbook documentation for details.

Configuring a Recipe

Now, lets go through the steps of adding a new recipe to the run-list to install Java.  (I've picked this one because you should already have the "java" cookbook in your berkshelf ... assuming you've cloned "nectar-cookbooks/chef-solo-repo" and run "berks install --path cookbooks" to install the dependencies.)

  1. Review the documentation for the "java" cookbook.  (You can find it here or here ... or in the "cookbooks/java/" file in your berkshelf.)
  2. Open your "mynode.json" file using your preferred text editor.
  3. Add the following attributes for the "java" cookbook after the "qcloud" attributes.  This says to install the Oracle version of Java 7; see cookbook documentation.

    "java" : {
    "install_flavor": "oracle",
    "jdk_version" : "7",
    "oracle" : {"accept_oracle_download_terms" : true}
  4. Change the run-list to this:

    "run-list : [
  5. Save the file.
  6. Run "chef-solo" as previously:
    sudo chef-solo -c solo/solo.rb -j mynode.json
Filed under: ,