Projects Meta Quick Hacks About

Running Chef-Shell with Chef-Zero in Test Kitchen

Nov 11, 2015

One of the things I find super useful in the Chef world is Chef-Shell (I think it used to be called Shef). It lets you load an interactive environment where you can debug your Chef code. One of the other things I love is Test-Kitchen.

One of the problems I’ve come up against a few times is trying to debug recipes against Chef-Zero in Chef-Shell on a Test-Kitchen provisioned node. Unfortunately, the Chef-Zero server only lasts the lifetime of the Test-Kitchen kitchen converge phase, even if the provision fails. Sometimes you want your Chef-Shell to have the full context of a run list, data bags etc. to be able to debug what’s going on.

To combat this, I put together a quick hack script which

  • Brings up a chef-zero server in the background
  • Uploads all the cookbooks, roles and data-bags to the chef-zero server
  • Runs chef-client to register the node in Zero
  • Dumps you into a chef-shell where you can debug to your hearts content
  • When you’re done with Chef-Shell just exit out and it kills the chef-zero server, so you can kitchen converge like normal

So… here’s the script

Using it is pretty simple, just bring up your Kitchen node with a kitchen converge, then download the script and run it. Then just use Chef-Shell with all the magic you’d expect in a full environment.

[vagrant@default-centos-71 ~]$ wget -q
[vagrant@default-centos-71 ~]$ test $(md5sum ./ | awk '{ print $1 }') == "2c22eeb0fc50aa19b5f3713c00277d94"; echo $?
[vagrant@default-centos-71 ~]$ sudo bash ./
Starting Chef Zero...
...running as 15452
Uploading cookbooks...
>> Starting Chef Zero (v4.3.2)...
>> WEBrick (v1.3.1) on Rack (v1.5.5) is listening at
>> Press CTRL+C to stop

Uploading apt          [2.9.2]
Uploading bluepill     [2.4.1]
Uploading build-essential [2.2.4]
Uploading nginx        [2.7.6]
Uploading ohai         [2.0.4]
Uploading packagecloud [0.1.0]
Uploading rsyslog      [2.2.0]
Uploading runit        [1.7.4]
Uploading w-nginx      [0.1.0]
Uploading yum          [3.8.2]
Uploading yum-epel     [0.6.4]
Uploaded all cookbooks.
Running chef-client...
[2015-11-11T17:53:33+00:00] INFO: Forking chef instance to converge...
[2015-11-11T17:53:33+00:00] INFO: *** Chef 12.5.1 ***
[2015-11-11T17:53:33+00:00] INFO: Chef-client pid: 27785
[2015-11-11T17:53:34+00:00] INFO: HTTP Request Returned 404 Not Found : Object not found:
[2015-11-11T17:53:34+00:00] INFO: Setting the run_list to ["recipe[w-nginx::default]"] from CLI options
[2015-11-11T17:53:34+00:00] INFO: Run List is [recipe[w-nginx::default]]
[2015-11-11T17:53:34+00:00] INFO: Run List expands to [w-nginx::default]
[2015-11-11T17:53:34+00:00] INFO: Starting Chef Run for default-centos-71
[2015-11-11T17:53:34+00:00] INFO: Running start handlers
[2015-11-11T17:53:34+00:00] INFO: Start handlers complete.
[2015-11-11T17:53:37+00:00] INFO: Chef Run complete in 2.871917848 seconds
[2015-11-11T17:53:37+00:00] INFO: Running report handlers
[2015-11-11T17:53:37+00:00] INFO: Report handlers complete
Starting chef-shell...
loading configuration: client.rb
Session type: client
resolving cookbooks for run list: []
Synchronizing Cookbooks:

This is the chef-shell.
 Chef Version: 12.5.1

run `help' for help, `exit' or ^D to quit.

Ohai2u vagrant@default-centos-71!
chef (12.5.1)> node.run_list.expand(node.chef_environment).recipes
 => ["w-nginx"]
chef > exit
Killing chef-zero server...

>> Stopping Chef Zero...
--- GOOD DAY ---
[vagrant@default-centos-71 ~]$

I’ve found this fairly useful, hopefully someone else does too.

/ smudge