Chef Commands
Chef is an infrastructure automation tool that transforms infrastructure into code, enabling configuration management, deployment, and infrastructure automation.
Installation
macOS
# Install Chef Workstation
brew install chef-workstation
# Verify installation
chef --version
knife --version
Linux (Ubuntu/Debian)
# Add Chef repository
curl https://packages.chef.io/files/stable/chef-workstation/21.10.1013/ubuntu/20.04/chef-workstation_21.10.1013-1_amd64.deb -o chef-workstation.deb
sudo dpkg -i chef-workstation.deb
# Verify
chef --version
Linux (RHEL/CentOS)
# Add Chef repository
sudo yum install https://packages.chef.io/files/stable/chef-workstation/21.10.1013/el/8/chef-workstation-21.10.1013-1.el8.x86_64.rpm
# Verify
chef --version
Basic Commands
| Command | Description |
|---|---|
chef --version | Display Chef version |
knife cookbook list | List cookbooks |
chef-client | Run Chef client |
chef-client -o recipe | Run specific recipe |
knife cookbook create myapp | Create cookbook |
chef-client --no-fork | Run in foreground |
chef-client --once | Run once |
knife help | Display help |
Cookbook Management
# Create new cookbook
chef generate cookbook myapp
# Create cookbook with berks
berks cookbook myapp
# Generate recipe in cookbook
chef generate recipe myapp default
# Generate resource
chef generate resource myapp myresource
# Generate template
chef generate template myapp config.erb
# Generate attribute file
chef generate attribute myapp default
# Generate cookbook from template
chef generate cookbook myapp -I apache2 -d "My app cookbook"
# List all cookbooks
knife cookbook list
# Show cookbook details
knife cookbook show myapp
# Delete cookbook
knife cookbook delete myapp
# Upload cookbook
knife cookbook upload myapp
Cookbook Structure
myapp/
├── attributes/
│ └── default.rb
├── recipes/
│ └── default.rb
├── templates/
│ └── config.erb
├── resources/
│ └── myresource.rb
├── libraries/
│ └── myhelpers.rb
├── spec/
│ ├── spec_helper.rb
│ └── unit/
│ └── recipes/
│ └── default_spec.rb
├── test/
│ └── integration/
│ └── default/
│ └── default_test.rb
├── metadata.rb
├── Berksfile
├── Rakefile
└── .kitchen.yml
Recipes
# Simple recipe (recipes/default.rb)
package 'apache2' do
action :install
end
service 'apache2' do
action [:enable, :start]
end
# Include other recipes
include_recipe 'apache2::default'
include_recipe 'mysql::server'
# Conditional recipe
if node['platform_family'] == 'debian'
package 'apache2' do
action :install
end
elsif node['platform_family'] == 'rhel'
package 'httpd' do
action :install
end
end
# Recipe with notification
file '/etc/apache2/apache2.conf' do
action :create
notifies :restart, 'service[apache2]'
end
# Execute command conditionally
execute 'enable_ssl' do
command 'a2enmod ssl'
not_if 'a2query -m ssl'
end
Resources
# Package resource
package 'git' do
action :install
end
# Service resource
service 'nginx' do
action [:enable, :start]
supports status: true, reload: true
end
# File resource
file '/etc/myapp.conf' do
owner 'root'
group 'root'
mode '0644'
content 'config content'
end
# Template resource
template '/etc/app/config.yaml' do
source 'app_config.yml.erb'
mode '0644'
notifies :restart, 'service[myapp]'
end
# Directory resource
directory '/var/www/myapp' do
owner 'www-data'
group 'www-data'
mode '0755'
recursive true
end
# Git resource
git '/var/www/myapp' do
repository 'https://github.com/user/myapp.git'
revision 'main'
action :sync
end
# Execute resource
execute 'bundle_install' do
command 'bundle install'
cwd '/var/www/myapp'
user 'www-data'
end
# Cron resource
cron 'daily_backup' do
hour '2'
minute '0'
weekday '0'
command '/usr/local/bin/backup.sh'
user 'root'
end
# User resource
user 'appuser' do
action :create
uid 1001
gid 1001
home '/home/appuser'
shell '/bin/bash'
end
# Group resource
group 'appgroup' do
action :create
gid 1001
end
Attributes
# attributes/default.rb
# Simple attribute
default['myapp']['version'] = '1.0.0'
# Nested attributes
default['myapp']['config']['database']['host'] = 'localhost'
default['myapp']['config']['database']['port'] = 5432
# Conditional attributes
if node['platform_family'] == 'debian'
default['apache']['package'] = 'apache2'
else
default['apache']['package'] = 'httpd'
end
# Array attributes
default['myapp']['gems'] = ['bundler', 'rails', 'puma']
# Access attributes in recipes
package node['apache']['package'] do
action :install
end
log "App version: #{node['myapp']['version']}"
Templates
<!-- templates/app_config.yml.erb -->
database:
host: <%= node['myapp']['db_host'] %>
port: <%= node['myapp']['db_port'] %>
username: <%= node['myapp']['db_user'] %>
<% if node['environment'] == 'production' %>
pool: 20
<% else %>
pool: 5
<% end %>
<% @packages.each do |package| %>
- <%= package %>
<% end %>
Testing
# Run cookbook tests
chef exec rspec
# Run kitchen tests
kitchen test
# Run kitchen converge
kitchen converge
# List kitchen instances
kitchen list
# Test specific recipe
kitchen converge ubuntu-20.04
# Run specific tests
rspec spec/unit/recipes/default_spec.rb
# Check cookbook style (foodcritic)
foodcritic .
# Lint cookbook (cookstyle)
cookstyle .
# Generate coverage report
chef exec rspec --format progress --format RspecJunitFormatter -o rspec.xml
Knife Commands
# List nodes
knife node list
# Show node details
knife node show node-name
# Edit node attributes
knife node run_list set node-name 'recipe[myapp]'
# Remove recipe from node
knife node run_list remove node-name 'recipe[myapp]'
# SSH to node
knife ssh 'name:node-*' 'uptime'
# Bootstrap node
knife bootstrap 192.168.1.100 -U ubuntu -P password -r 'recipe[myapp]'
# Bootstrap with identity file
knife bootstrap 192.168.1.100 -x ubuntu -i ~/.ssh/id_rsa -r 'recipe[myapp]'
# Show node run list
knife node run_list show node-name
# Edit node data
knife node edit node-name
# Delete node
knife node delete node-name
Chef-Client
# Run Chef client
sudo chef-client
# Run specific recipe
sudo chef-client -o recipe[myapp]
# Run with log level
sudo chef-client -l debug
# Run in local mode
sudo chef-client -z
# Validate config only
sudo chef-client --config-option-verify
# Run once
sudo chef-client -o
# Run without forking
sudo chef-client --no-fork
# Enable/disable client
sudo chef-client -d 'Maintenance' # disable with reason
sudo chef-client -e # enable
# Reset node
knife node delete node-name
knife client delete node-name
Berksfile (Dependency Management)
# Berksfile
source 'https://supermarket.chef.io'
metadata
# Cookbook dependencies
cookbook 'apache2', '~> 8.0.0'
cookbook 'postgresql', '~> 11.0.0'
cookbook 'nodejs', github: 'chef-cookbooks/nodejs'
# Git dependencies
cookbook 'myapp', git: 'https://github.com/user/myapp-cookbook.git', branch: 'main'
# Local path dependencies
cookbook 'local_cookbook', path: './local_cookbook'
Berkshelf Commands
# Install dependencies
berks install
# Update dependencies
berks update
# Upload cookbooks
berks upload
# List dependencies
berks list
Environments
# Create environment
knife environment create production
# Show environment
knife environment show production
# Edit environment
knife environment edit production
# List environments
knife environment list
# Set cookbook version constraints
knife environment edit production
# In editor:
# "cookbook_versions": {
# "apache2": "= 8.0.0",
# "mysql": "~> 5.0.0"
# }
Data Bags
# Create data bag
knife data bag create users
# Add item to data bag
knife data bag create users user1
# Show data bag item
knife data bag show users user1
# Edit data bag item
knife data bag edit users user1
# List data bags
knife data bag list
# Delete data bag item
knife data bag delete users user1
# Encrypt data bag
knife data bag create --secret-file /path/to/secret users passwords
Using Data Bags in Recipes
# Load data bag
users = data_bag_item('users', 'user1')
# Use data bag data
user users['username'] do
uid users['uid']
home users['home']
shell users['shell']
end
Best Practices
- Write idempotent recipes (safe to run multiple times)
- Use attributes for configuration
- Organize code into logical cookbooks
- Test cookbooks with kitchen and rspec
- Use version constraints for dependencies
- Document cookbooks and recipes
- Use templates for configuration files
- Implement proper error handling
- Use notifications for resource ordering
- Follow community guidelines and standards
- Use data bags for secrets (encrypted)
- Monitor chef-client runs
- Implement gradual deployments
- Use roles for node classification
Resources
Last updated: 2026-03-30|Chef 17+