cheat-sheets

Chef

Chef is a configuration management tool: you describe the desired state of a machine in Ruby based recipes, group them in cookbooks, and chef-client converges the node towards that state. Chef Workstation bundles the tools you use on your own machine (chef, knife, kitchen, cookstyle, inspec). Nothing here was run: the commands, resources and file layouts come from the Chef documentation and are unverified, so confirm with --help or knife --help on your installed version before relying on a flag. Compare with Ansible, Puppet and Salt.

Documentation: Chef docs Project: chef/chef


Cookbook Layout #

PATHPURPOSE
metadata.rbName, version, dependencies (depends 'other'), supported platforms
recipes/default.rbThe default recipe (a list of resources)
attributes/default.rbDefault attribute values
templates/ERB templates for the template resource
files/Static files for cookbook_file
resources/Custom resources
libraries/Ruby helpers
kitchen.ymlTest Kitchen configuration
test/InSpec profiles and other tests

chef CLI (Workstation) #

COMMANDDESCRIPTION
chef generate cookbook NAMECreate a cookbook skeleton
chef generate recipe NAME RECIPEAdd a recipe (run inside the cookbook directory or give a path)
chef generate attribute / template / file / resourceAdd other cookbook parts (each takes a name)
chef generate repo NAMECreate a Chef repository
chef exec COMMANDRun a command using Workstation’s Ruby and gems
chef shell-init bashPrint the shell setup that puts Workstation’s tools first on the path
chef gem install NAMEInstall a gem into Workstation’s Ruby
chef envShow the Workstation environment
chef install / chef updateResolve and update a Policyfile lock
chef push POLICY_GROUPPush a policy to a policy group on the server
chef --versionShow the version

knife #

knife talks to a Chef Infra Server using config.rb (usually in .chef/ or ~/.chef/) and your API key.

COMMANDDESCRIPTION
knife ssl checkCheck the server certificate is trusted
knife ssl fetchDownload the server certificate into the trusted certificate store
knife node list / node show NAMEList nodes, show one
knife node edit NAMEEdit a node’s JSON in your editor
knife node delete NAMEDelete a node object (destructive)
knife node run_list add NAME 'recipe[COOKBOOK]'Add to a node’s run list
knife node run_list remove NAME 'recipe[COOKBOOK]'Remove from a run list
knife node run_list set NAME 'role[web],recipe[ntp]'Replace the run list
knife role list / role show NAME / role from file FILE.jsonRoles
knife environment list / environment from file FILE.jsonEnvironments
knife data bag create NAMECreate a data bag
knife data bag from file NAME ITEM.jsonUpload an item (--secret-file FILE encrypts it)
knife data bag show NAME ITEMShow an item
knife cookbook upload NAMEUpload a cookbook from the cookbook path (-a uploads all)
knife cookbook list / cookbook show NAMEList or show cookbooks on the server
knife cookbook delete NAME VERSIONDelete a cookbook version from the server (destructive)
knife search node 'platform:ubuntu'Search node data (also knife search role ...; add -a ATTRIBUTE to print one attribute)
knife statusWhen each node last checked in
knife client listAPI clients (client delete NAME is destructive)
knife ssh 'role:web' 'sudo chef-client'Run a command on nodes found by search
knife bootstrap HOST -N NODE_NAME -x USER --sudo -r 'recipe[COOKBOOK]'Install the client on a machine and run it (-x SSH user, -i KEY, -E ENVIRONMENT, --policy-name, --policy-group)
knife exec SCRIPT.rbRun a Ruby script against the server API
knife config listShow the configuration knife is using

chef-client #

COMMANDDESCRIPTION
chef-clientConverge this node against the server
chef-client -zLocal mode: run with an in-memory Chef server using local files
chef-client -z -o 'recipe[COOKBOOK]'Local mode with an override run list
chef-client -o 'recipe[COOKBOOK]'Override the run list for one run
chef-client -j attributes.jsonSupply JSON attributes (can set a run_list)
chef-client -WWhy-run: report what would change without changing it
chef-client -l debugLog level
chef-client -L FILELog to a file
chef-client -i 1800 -s 300Run as a loop every interval seconds, with splay
chef-client -E ENVIRONMENTSet the environment
chef-client -c FILEUse a specific client.rb
chef-client --chef-license acceptAccept the licence non-interactively
chef-apply FILE.rbRun a single recipe file without a cookbook

chef-solo is deprecated in favour of local mode (chef-client -z): treat it as legacy.

Recipe Resources #

ruby
package 'nginx' do
  action :install
end

template '/etc/nginx/nginx.conf' do
  source 'nginx.conf.erb'
  owner 'root'
  group 'root'
  mode '0644'
  variables(workers: node['nginx']['workers'])
  notifies :reload, 'service[nginx]', :delayed
end

service 'nginx' do
  action [:enable, :start]
end

directory '/var/www/app' do
  owner 'www-data'
  recursive true
end

execute 'build-index' do
  command '/usr/local/bin/build-index'
  creates '/var/lib/app/index.db'
end
RESOURCEPURPOSE
packageInstall, upgrade or remove a package
service:enable, :disable, :start, :stop, :restart, :reload
template / cookbook_file / fileWrite config from ERB, from a cookbook file, or inline content
directory / linkDirectories and symlinks
execute / scriptRun commands; make them idempotent with creates, only_if or not_if
user / groupAccounts
cron / systemd_unitScheduled jobs and unit files
remote_file / gitDownload a file, check out a repository
apt_package / dnf_packagePlatform specific packages

Common meta properties: action, only_if, not_if, notifies :action, 'resource[name]', :immediately|:delayed, subscribes. A resource runs in the order written; notifications are queued and, with :delayed, run once at the end of the run.

Attributes #

ruby
# attributes/default.rb
default['nginx']['workers'] = 2

node['nginx']['workers'] reads the merged value. Precedence, lowest to highest: default, force_default, normal, override, force_override, automatic. Role, environment and policy levels are also layered into default and override (see the docs for the full table). Prefer default in cookbooks and override in roles or environments.

Data Bags #

COMMANDDESCRIPTION
knife data bag create usersCreate a bag
knife data bag from file users alice.jsonAdd an item
knife data bag from file secrets db.json --secret-file FILEAdd an encrypted item
data_bag_item('users', 'alice')Read an item in a recipe
search(:users, 'groups:sudo')Search a bag in a recipe

Test Kitchen #

Test Kitchen builds a throwaway instance, converges your cookbook on it and runs tests.

COMMANDDESCRIPTION
kitchen listInstances and their state
kitchen create / converge / verifyMake the instance, apply the cookbook, run the tests
kitchen testFull cycle: create, converge, verify, destroy
kitchen login INSTANCEShell into an instance
kitchen destroyRemove instances
kitchen diagnoseShow the resolved configuration
kitchen converge -c 2Run instances concurrently
yaml
# kitchen.yml
driver:
  name: dokken

provisioner:
  name: dokken

verifier:
  name: inspec

platforms:
  - name: ubuntu-24.04
    driver:
      image: dokken/ubuntu-24.04

suites:
  - name: default
    run_list:
      - recipe[COOKBOOK::default]
    verifier:
      inspec_tests:
        - test/integration/default

The dokken driver (container based) needs the kitchen-dokken gem and Docker. Other drivers include vagrant (see Vagrant).

COMMANDDESCRIPTION
cookstyle .Lint cookbook Ruby (-a auto-corrects safe offences)
inspec init profile NAMECreate a test profile
inspec exec PROFILERun a profile locally (-t ssh://USER@HOST for a remote host)
inspec check PROFILECheck a profile is valid

Troubleshooting #

SYMPTOMFIX
SSL certificate verify failed from knifeknife ssl fetch then knife ssl check
Resource runs every timeNot idempotent: add creates, only_if or not_if to execute
Template change does not restart the serviceAdd notifies :restart, 'service[NAME]' to the template
Attribute has the wrong valueCheck precedence levels; knife node show NAME -l or node.debug_value('KEY') shows where it came from
Cookbook dependency missingAdd depends in metadata.rb and upload the dependency
Run is slow or unclearchef-client -l debug, and -W to see what would change
Want to test without a serverchef-client -z -o 'recipe[NAME]' or kitchen test

See Also #

Search all sheets

Tip: / or Ctrl/Cmd+K to open, Esc to close.