Run Chef Shell with Chef Zero

From Bonus Bits
Jump to: navigation, search


This article gives the steps to run Chef Shell against local Chef Zero. The example is from a Test Kitchen instance. This can be good to debug your chef code. Such as, testing searches and listing resolved node attribute values.


  • Stand up instance with Test Kitchen
  • Login to instance
    • kitchen login

Example Kitchen Config

To help clarify the setup the following examples are using here is a snippet of the .kitchen.yml pertaining to to Chef configurations for Test Kitchen. Since I use Chef Zero and not server even for actual deployments, I use generic chef content names i.e. ec2_role. I lay down the ec2_environment.json with CloudFormation to plug in dynamic values for the Chef run to pick up.


  name: chef_zero
  require_chef_omnibus: 12.18.31
  data_bags_path: test/data_bags
  encrypted_data_bag_secret_key_path: test/data_bags/encrypted_data_bag_secret
  roles_path: test/roles
  environments_path: test/environments

Cookbook Test Folder Structure

Here is the basic cookbook test folder layout that has the chef configuration JSON files that Test Kitchen uploads to the instance. I excluded the integration subfolders.

├── data_bags
│   ├── ec2_databags
│   │   ├── ec2_databag.json
│   └── encrypted_data_bag_secret
├── environments
│   ├── ec2_environment.json
└── roles
    └── ec2_role.json


node_name "default"
checksum_path "/tmp/kitchen/checksums"
file_cache_path "/tmp/kitchen/cache"
file_backup_path "/tmp/kitchen/backup"
cookbook_path ["/tmp/kitchen/cookbooks", "/tmp/kitchen/site-cookbooks"]
data_bag_path "/tmp/kitchen/data_bags"
environment_path "/tmp/kitchen/environments"
node_path "/tmp/kitchen/nodes"
role_path "/tmp/kitchen/roles"
client_path "/tmp/kitchen/clients"
user_path "/tmp/kitchen/users"
validation_key "/tmp/kitchen/validation.pem"
client_key "/tmp/kitchen/client.pem"
chef_server_url ""
encrypted_data_bag_secret "/tmp/kitchen/encrypted_data_bag_secret"
treat_deprecation_warnings_as_errors false
environment "ec2_environment"

Start Chef Zero

First we need to start Chef Zero in memory. We could just run Chef Zero and with another terminal session run our Chef Shell, but in this example, we'll be running Chef Zero as a background process so we don't need two sessions.

/opt/chef/embedded/bin/chef-zero -d
/opt/chef/embedded/bin/chef-zero  > /dev/null  2>&1 &

Icon-Tip-Square-Green.png Take note of the PID output when starting Chef Zero in the background so we can kill it when done. i.e. [1] 29759

Upload Chef Content to Chef Zero

Now we need to upload all our Chef content such as roles, environments, data bags and cookbooks to the Chef Zero in-memory instance. This example shows uploading all the Chef content in the kitchen temp directory. We could individually pick and chose each item to upload with standard knife commands. The options have to come after the knife subcommand.

cd /tmp/kitchen
knife upload . -c client.rb


Created data_bags/ec2_databags
Created environments/ec2_environment.json
Created roles/ec2_role.json
Created data_bags/ec2_databags/ec2_databag.json
Created cookbooks/bonusbits_mediawiki_nginx

Run Chef Shell

Again this example is on an instance that was created by Test Kitchen. So, we can use the generated client.rb to point to all of our Chef Client settings. Which if kitchen was configured to use Chef Zero (recommended) then it will already have the URL set in the client.rb. Otherwise, if not we can append this to the end of the command -S

/opt/chef/bin/chef-shell -z -c /tmp/kitchen/client.rb -o role[ec2_role]
/opt/chef/embedded/bin/chef-shell -z -c /tmp/kitchen/client.rb -j /tmp/kitchen/dna.json


loading configuration: /tmp/kitchen/client.rb
Session type: client
Loading...[2017-03-06T21:26:11+00:00] WARN: Run List override has been provided.
[2017-03-06T21:26:11+00:00] WARN: Original Run List: []
[2017-03-06T21:26:11+00:00] WARN: Overridden Run List: [role[ec2_role]]
resolving cookbooks for run list: ["bonusbits_mediawiki_nginx"]
Synchronizing Cookbooks:
.  - bonusbits_mediawiki_nginx (0.7.0)

This is the chef-shell.
 Chef Version: 12.18.31

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

chef (12.18.31)>

Kitchen Summary

Kitchen Created VM

/opt/chef/embedded/bin/chef-zero -d
cd /tmp/kitchen
knife upload . -c client.rb
/opt/chef/embedded/bin/chef-shell -z -c /tmp/kitchen/client.rb -j /tmp/kitchen/dna.json

Chef Client Summary

Package Chef Content

  1. Download latest cookbooks and package up with Berkshelf. From root of you cookbook archive it and all dependancies with Berkshelf (Assuming Berksfile updated for any non Chef Supermarket Community cookbooks).
berks update && berks package
  1. Upload cookbooks.tar.gz to the instance


mkdir /opt/chef_repo
cd /opt/chef_repo && mkdir -p backup cache checksums cookbooks data_bags environments roles
tar -xzvf /tmp/cookbooks.tar.gz -C /opt/chef_repo
cp /opt/chef_repo/cookbooks/mycookbook/test/environments/environment.json /opt/chef_repo/environments
cp /opt/chef_repo/cookbooks/mycookbook/test/roles/role.json /opt/chef_repo/roles
cp -R /opt/chef_repo/cookbooks/mycookbook/test/data_bags/* /opt/chef_repo/data_bags
├── backup
├── cache
├── checksums
├── cookbooks
│   ├── mycookbook
│   │   ├── recipes
├── data_bags
│   ├── databag
│   │   ├── databag_item.json
│   └── encrypted_data_bag_secret
├── environments
│   ├── environment.json
└── roles
    └── role.json

Client File

vim /opt/chef_repo/client.rb
node_name 'default'
file_backup_path '/opt/chef_repo/backup'
checksum_path '/opt/chef_repo/checksums'
file_cache_path '/opt/chef_repo/cache'
cookbook_path '/opt/chef_repo/cookbooks'
data_bag_path '/opt/chef_repo/data_bags'
environment_path '/opt/chef_repo/environments'
role_path '/opt/chef_repo/roles'
chef_server_url ''
encrypted_data_bag_secret '/opt/chef_repo/data_bags/encrypted_data_bag_secret'
log_level :info
log_location '/var/log/chef-client.log'
verify_api_cert false
treat_deprecation_warnings_as_errors false
environment "environment"
role "role"

Start Chef-Zero > Upload Files > Run Chef-Shell

/opt/chef/embedded/bin/chef-zero -d
cd /opt/chef_repo
knife upload . -c client.rb
/opt/chef/bin/chef-shell -z -c /tmp/kitchen/client.rb


Here are a few simple commands to test that the environment is setup correctly.


Exit Chef Shell

After debugging your issues and saving the world... a simple exit <enter> will eject from the Chef Shell

Stop Chef Zero

Grab that PID that was displayed when starting Chef Zero in the background and use the kill command to end the process.

kill -9 29759

Gnome-sticky-notes-applet.png If we have forgotten what the number was, we can simply close the SSH session which will kill the background process or use ps hf -opid -C chef-zero to discover the PID.

Related Articles