Chef is a configuration management tool written in Ruby and Erlang. It automates the process of configuring, deploying, and managing servers and infrastructure.
- Node: A machine (physical/virtual) managed by Chef.
- Cookbook: A collection of recipes and other config files.
- Recipe: The fundamental unit for configuration — contains Ruby code to define resources.
- Resource: A statement of configuration like
package,service,file, etc. - Runlist: A list of recipes/roles applied to a node.
🟢 Beginner Commands (Click to Expand)
chef --versionchef generate cookbook my_cookbookchef generate recipe my_cookbook defaultchef-client --local-mode --runlist 'recipe[my_cookbook]'ruby -c recipes/default.rb🟡 Intermediate Commands (Click to Expand)
knife bootstrap <IP_ADDRESS> -x user -P password --node-name node1knife cookbook upload my_cookbookknife node show node1knife ssh 'name:node1' 'sudo chef-client' -x user🔴 Advanced Commands (Click to Expand)
knife search node 'role:web'
knife data bag show usersknife node edit node1
knife role edit webserverchef generate role webserver
chef generate environment devknife role from file roles/webserver.rb
knife environment from file environments/dev.rbchef exec rspec
chef exec inspec exec test/integration/default# Install Chef Workstation
curl -LO https://packages.chef.io/files/stable/chef-workstation/latest/el/7/chef-workstation-*.rpm
sudo rpm -Uvh chef-workstation-*.rpm# Verify installation
chef -vchef generate cookbook my_cookbook
cd my_cookbook# recipes/default.rb
package 'nginx'
service 'nginx' do
action [:enable, :start]
end# Run recipe on local machine (Test Kitchen or chef-run)
chef-run 'localhost' my_cookbook| Resource | Example |
|---|---|
package |
package 'nginx' |
service |
service 'nginx' { action [:start, :enable] } |
file |
file '/etc/motd' { content 'Hello Chef' } |
user |
user 'deploy' { shell '/bin/bash' } |
# attributes/default.rb
default['my_cookbook']['greeting'] = 'Welcome to Chef!'
# Use in recipe
file '/etc/motd' do
content node['my_cookbook']['greeting']
endTemplates are ERB files used to manage config files.
# generate template
mkdir templates/default
touch templates/default/index.html.erb<!-- templates/default/index.html.erb -->
<h1>Hello <%= node['hostname'] %>!</h1># recipes/default.rb
template '/var/www/html/index.html' do
source 'index.html.erb'
end# Create data bag and item
knife data bag create users
knife data bag from file users user1.json// users/user1.json
{
"id": "user1",
"uid": "1001",
"shell": "/bin/bash"
}# Use in recipe
user_data = data_bag_item('users', 'user1')
user user_data['id'] do
uid user_data['uid']
shell user_data['shell']
end# Create role file
knife role create webserver{
"name": "webserver",
"run_list": [
"recipe[my_cookbook::default]"
]
}Used to manage differences between dev, test, prod.
# Create environment
knife environment create dev{
"name": "dev",
"default_attributes": {
"my_cookbook": {
"greeting": "Welcome to Dev Environment"
}
}
}# inside cookbooks/my_cookbook/resources/hello.rb
resource_name :hello
property :name, String, name_property: true
action :create do
file "/tmp/#{name}" do
content "Hello, #{name}!"
end
end# recipes/default.rb
hello 'chef_user'# spec/unit/recipes/default_spec.rb
require 'chefspec'
describe 'my_cookbook::default' do
let(:chef_run) { ChefSpec::SoloRunner.new.converge(described_recipe) }
it 'installs nginx' do
expect(chef_run).to install_package('nginx')
end
endRun tests:
rspec# .kitchen.yml
driver:
name: vagrant
provisioner:
name: chef_zero
platforms:
- name: ubuntu-20.04
suites:
- name: default
run_list:
- recipe[my_cookbook::default]kitchen converge
kitchen verifyAlternative to Berkshelf and runlists.
chef generate policyfile my_policy# Policyfile.rb
name 'my_policy'
run_list 'my_cookbook::default'
default_source :supermarket
cookbook 'my_cookbook', path: '.'chef install
chef push my_org my_policy.lock.jsonChef Automate provides UI and compliance, visibility, and workflow capabilities.
- Setup dashboards
- Integrate with InSpec for audits
- Workflow pipelines for cookbook CI/CD
knife bootstrap IP_ADDRESS -x user -P password --node-name NODE_NAME
knife node list
knife cookbook upload my_cookbook
knife role from file webserver.json- Keep cookbooks modular and reusable.
- Use Berkshelf or Policyfiles to manage dependencies.
- Write tests (ChefSpec/Test Kitchen) for stability.
- Avoid hardcoding; use attributes or data bags.
- Prefer custom resources over LWRPs.
