Table of Contents
What Chef Is in the Configuration Management Landscape
Chef is a configuration management and automation tool that treats your infrastructure as code using Ruby-based DSLs. Compared with other tools:
- It is pull-based by default: nodes reach out to a central server to get their configuration.
- It is built around Ruby; most configuration is Ruby code, not pure data (like YAML in some other tools).
- It has a strong focus on idempotent “resources” (e.g.,
package,service,file) that describe the desired state of a node.
In the context of this course, see Chef as one of the major CM tools alongside Ansible and Puppet, but with its own model and terminology.
Key Concepts and Terminology
Node
A node is any system managed by Chef: physical server, VM, container, cloud instance, etc.
Each node typically runs the Chef client and periodically contacts the Chef server to:
- Authenticate
- Retrieve its configuration
- Apply changes to match the desired state
Chef Server
The Chef Server is the central place where:
- Cookbooks and policies are stored
- Nodes check in and retrieve their configuration
- Node data (like run history, attributes, environment) is stored
In small labs you might also see Chef Solo or Chef Zero, which remove the central server and let you run locally for testing or simple setups.
Workstation
The workstation is where you, the administrator or DevOps engineer, work from. From the workstation you:
- Write and edit cookbooks
- Test them locally or with test tools
- Upload them to the Chef server
- Manage nodes and policies using
knifeor other tooling
Cookbooks, Recipes, and Resources
These are the heart of Chef:
- Cookbook
A collection of configuration code and supporting files for a specific purpose (e.g.,nginx,users,myapp). A cookbook usually contains: - One or more recipes
- Templates (e.g.,
.erbfiles) - Files, attributes, tests, etc.
- Recipe
A recipe is a Ruby file that describes how a system should be configured, using resources. Example tasks: install packages, configure services, place files, run commands. - Resource
A resource is a building block that manages a specific part of the system in an idempotent way. Examples: package 'nginx'service 'nginx'file '/etc/app.conf'user 'deploy'
Chef resources describe the desired state, and Chef figures out what needs to be changed to achieve that state.
Run List
The run list tells Chef what to apply on a node during a run. It can include:
- Recipes from cookbooks
- Roles (which themselves list recipes)
Example conceptually: “this node should run recipe[base] and recipe[webserver]”.
Attributes
Attributes are key–value data that affect how recipes behave. They can describe things like:
- Package versions
- File paths
- Service ports
- Environment-specific differences
Attributes can come from multiple sources and have a precedence model (node, role, environment, etc.).
Roles and Environments
- Role
A role represents a function of a node (e.g.,webserver,database,load_balancer). It typically defines: - A run list
- Attributes specific to that role
- Environment
Environments group nodes by lifecycle stage (e.g.,dev,staging,production), allowing: - Different configuration settings
- Different cookbook versions per environment
How Chef Works: The Basic Workflow
At a high level, the workflow looks like this:
- On the workstation
- Install Chef tooling.
- Create or modify cookbooks (and recipes).
- Test changes locally.
- Upload cookbooks and related data to the Chef Server.
- On each node
- Install the Chef client.
- Register the node with the Chef server (usually once).
- Assign a run list (and possibly roles and environment).
- During a Chef run (convergence)
- Node’s Chef client:
- Authenticates with Chef server.
- Retrieves its run list and relevant cookbooks.
- Compiles all recipes into a resource collection.
- Executes resources in order to reach the desired state.
- Chef sends updated node data back to the server (attributes, run status, etc.).
Chef calls this process convergence: bringing a node into compliance with the declared configuration.
Example: A Minimal Recipe
Even though other chapters might show more complex examples, a simple recipe illustrates how Chef feels:
package 'nginx' do
action :install
end
service 'nginx' do
action [:enable, :start]
end
file '/var/www/html/index.html' do
content "<h1>Hello from Chef</h1>\n"
mode '0644'
owner 'www-data'
group 'www-data'
endConceptually this says:
- Ensure the
nginxpackage is installed. - Ensure the
nginxservice is enabled at boot and currently running. - Ensure a specific index file exists with the given content, owner, and permissions.
If you run this recipe multiple times, Chef will only make changes when something is out of sync.
Chef’s Architecture Style
Pull-Based Model
Chef is primarily pull-based:
- Each node initiates communication to the Chef server on a schedule (e.g., every 15 or 30 minutes).
- This scales well and works behind firewalls/NAT more easily, because nodes are the clients.
Some workflows can appear “pushy” using tools like knife ssh or chef-push, but the core design is pull.
Ruby DSL and Flexibility
Chef recipes are Ruby code, not pure data descriptions. This gives:
- Flexibility: conditionals, loops, reuse, simple logic in recipes.
- Complexity for beginners: you need at least basic Ruby understanding for non-trivial logic.
Where Chef Fits Best
Chef is often used in:
- Large infrastructures with many Linux (and also Windows) nodes.
- Cloud environments (AWS, Azure, GCP) where instances come and go and need to converge to a known state.
- Organizations that:
- Prefer pull-based configuration management.
- Are comfortable with Ruby as a configuration language.
- Want strong support for policy-based configuration (roles/environments, versioned cookbooks).
Typical tasks handled by Chef:
- Installing and configuring common services (web servers, DBs, app servers).
- Managing users, permissions, and system settings.
- Deploying application code (often combined with other tools).
Comparison Points (High-Level)
Without going deep into other tools’ internals (which are covered elsewhere in the course), keep these high-level distinctions in mind:
- Compared to Ansible
- Chef: server–client, pull-based, Ruby DSL.
- Ansible: typically agentless and push-based, YAML playbooks.
- Compared to Puppet
- Both: server–agent, pull-based, concept of resources and desired state.
- Puppet: declarative language (not Ruby), different ecosystem and tooling.
- Chef: recipes are Ruby, cookbook structure is central.
These differences affect how you design your workflows and what skills your team needs.
Learning and Using Chef as a Beginner
If you want to get hands-on with Chef in a simple way:
- Set up a workstation on a Linux VM.
- Use local modes (like Chef Solo/Chef Zero) to:
- Write a small cookbook.
- Create a recipe that installs a package and sets up a file.
- Try running the recipe repeatedly to see the idempotent behavior.
- Explore how to define a run list and apply different recipes to different nodes in a small lab.
Even without building a full Chef server setup, this gives you a sense of:
- How Chef describes system state using resources.
- How infrastructure-as-code works using its Ruby DSL.
- How you could scale this approach to many servers later.