Chef Parts
Recipe
A recipe is a single set of instructions that describes one piece of desired system state. It tells Chef what should be true on a server—such as a package being installed, a service running, or a config file having specific contents. Recipes are declarative and idempotent, meaning they can be run repeatedly and will only make changes if something is out of place.
Think of a recipe as one task or responsibility.
Cookbook
A cookbook is a container that groups related recipes and supporting files. It represents everything needed to configure a particular component or role (for example, a web server or database). A cookbook can include multiple recipes, templates, files, attributes, and metadata. On its own, a cookbook doesn’t do anything until its recipes are selected to run.
Think of a cookbook as a project or module that holds all the instructions for a specific purpose.
What is a Policy in Chef?
A policy (specifically a Policyfile) is the decision layer in Chef. It defines which recipes run, which versions of cookbooks are used, and on what type of system. A policy does not contain configuration logic itself; instead, it selects and locks the exact configuration that should be applied to a node.
In simple terms, a policy answers the question: “For this server, what should be applied?
How they are related
Recipes live inside cookbooks. A cookbook may have one recipe or many, each handling a specific part of configuration. Chef runs recipes (not cookbooks directly), and it runs them based on a policy or run list that tells Chef which recipes to apply to a server.
In practice, you design small, focused recipes and group them into a cookbook so they can be reused and combined across different servers.
Declarative Configuration in Chef (Recipes and Policies)
In Chef, declarative configuration is implemented through recipes. Each recipe describes a specific responsibility, such as configuring a connection broker, setting up a profile server, or applying default security settings. Breaking configurations into smaller recipes makes them easier to understand, maintain, and reuse.
Chef encourages breaking recipes into shared and specialized (niche) recipes. For example, you might create a shared recipe that applies default server settings, such as logging or security hardening. That same recipe can then be reused across multiple servers, including a connection broker, profile server, or session host. This prevents code duplication and ensures consistency.
There is no practical limit to how many recipes you can create. This flexibility allows you to design clean, modular configurations where each recipe has a single responsibility. When requirements change, you update one recipe and all systems that use it benefit automatically.
Policies, Bootstrapping, and Execution Flow
Chef uses policies to define which recipes should run on which systems. A policy acts like a menu, listing the recipes that apply to a specific type of server. When a client is bootstrapped, it is told which policy to use. The policy then determines which recipes are executed and in what context.
This separation between recipes and policies makes infrastructure highly flexible. You can apply different combinations of recipes to different servers without rewriting code. Shared recipes handle common functionality, while specialized recipes handle role-specific behavior.
A useful analogy is a menu for guests. You don’t rewrite the recipes each time you host someone; instead, you choose which dishes to serve based on the guests. In the same way, Chef policies select the appropriate recipes for each server role.
Policyfiles are the concrete implementation of the “menu” concept in Chef—they define, lock, and enforce which recipes run on a server when it is bootstrapped and managed.
Kitchen
Test Kitchen (often just called Kitchen) is a testing tool used with Chef to safely test cookbooks and recipes before they are applied to real servers. Instead of guessing whether a recipe will work, Kitchen creates a temporary test environment, runs the Chef code, and lets you confirm that the system ends up in the desired state. This helps catch mistakes early and prevents breaking production systems.
Kitchen works by automatically creating a temporary machine, applying the Chef recipes to it (a process called converge), optionally verifying the result, and then destroying the machine when testing is finished. Because the test system is disposable, it can be created and destroyed repeatedly without risk. This makes Chef development more reliable and repeatable.
Kitchen ensures that the policy + cookbook + recipes work correctly before production.
EC2 Kitchen
AWS EC2 can be used as the testing environment for Kitchen. When EC2 is selected as the driver, Kitchen uses Amazon Web Services to launch a real cloud virtual machine. The EC2 instance acts as a short-lived test server where Chef runs exactly as it would in production. This is especially useful when production systems already run on AWS, because the test environment closely matches the real one.
Once the Chef recipes finish running on the EC2 instance, Kitchen can verify that everything worked as expected and then terminate the instance. This ensures accurate testing on real cloud infrastructure while keeping costs low and avoiding permanent resources. In simple terms, Kitchen uses EC2 as a temporary practice server to test Chef code safely before real deployment.
Attributes
Attributes are variables used in Chef cookbooks to store configuration values. Instead of hard-coding values directly into recipes, you place them in attributes so the same recipe can be reused across different servers, environments, or organizations.
Knife
knife is the remote control for Chef.
knife is the command-line tool used by administrators to interact with Chef from the Chef Workstation. It’s how you manage Chef Server objects (nodes, cookbooks, policies, environments, data bags) and control infrastructure without logging into servers manually.
With knife, you can:
- Upload cookbooks and policies to the Chef Server
- Manage nodes (list, inspect, delete)
- Bootstrap new servers (install Chef/CINC and register the node)
- Query data (search nodes, environments, attributes)
- Interact with cloud providers (AWS, Azure) via plugins
All from your workstation.
Data Bag
A data bag is a central storage place for shared data in Chef that is separate from recipes and cookbooks. It holds information that many nodes may need—such as user accounts, application settings, or credentials—without hard-coding those values into code.
Imagine a company called Acme Corp with hundreds of servers across the organization. These servers support different departments such as IT, Finance, HR, and Customer Support. Many of these servers need the same users, permissions, and access rules applied consistently.
Instead of hard-coding user accounts into every Chef recipe, Acme Corp creates a data bag called users. This data bag stores shared user information in one central place. Each item in the data bag represents a user, including their username, department, groups, and SSH keys.
When Chef runs on any server, a recipe reads from the users data bag and creates or manages those user accounts automatically. If a new employee joins the company, IT adds a new user entry to the data bag. On the next Chef run, that user is created on all relevant servers. If someone leaves the company, their entry is removed from the data bag, and Chef removes their access everywhere.