Simple Chef: chef-solo

Sometimes you just need to run some Chef code directly on a node and don’t want to deal with changing what is on your Chef Server.  Chef-solo to the rescue.  Say you have a problem with some node and you need to debug the problem on that specific node.  Or maybe you have an idea for a possible improvement and just want to try it out without going through the process of releasing a new version to the Chef server.  Or maybe you need to debug Chef at the Ruby level.

This technique is usable whether you are working on a machine that already runs chef-client and gets its configuration from a Chef server, or you are logged in to a Test Kitchen VM that has perhaps failed to converge.  The examples are based on Windows, but the idea is same regardless of platform.  I created a folder called C:\solo to put the following Chef-solo configuration files.  You will also need to create C:\solo\environments.

  • C:\solo.rb (client configuration: location of cookbooks, environments, etc.)
  • C:\solo.json (node configuration: run list and attributes)
  • C:\environments\env.json (an environment is mandatory)
  • C:\cookbooks\ (to put cookbooks, of course)
C:\solo.rb
cookbook_path [
 'c:\cookbooks'
 ]
environment_path [
 'c:\environments'
 ]
environment 'env'
log_level :info
log_location STDOUT
node_name 'the-node-name'
solo.json
{
 "name": "the-node-name",
 "run_list": [
 "recipe[some_cookbook::some_recipe]"
 ]
}
C:\environments\env.json
{
 "name": "env",
 "description": "an environment",
 "json_class": "Chef::Environment",
 "chef_type": "environment"
}

Note that you can set the cookbook_path in solo.rb to point to Chef’s cache directory (usually C:\chef\cache or a real node, or c:\users\vagrant\appdata\local\temp\kitchen on a Test Kitchen VM).  This will allow you to run any or all of the recipes that are cached on that node.

Now you can simply converge the recipes specified in solo.json as follows:

chef-solo -c solo.rb -j solo.json

If you want to see in (gory) detail what Chef is doing, turn on debugging:

chef-solo -c solo.rb -j solo.json -l debug

The nice thing about this setup is that you can edit files in the cache directory to try out changes to the Chef code locally on a node.  Even better, you can use a tool like pry to dorp into an interactive Ruby environment from anywhere in your Chef code and snoop around.  This can be useful when trying to debug what is actually happening after all the Chef DSL is compiled into actual Ruby code.  Good luck!