CoursesChefBeginner

Resources & recipes

The declarative Ruby building blocks.

Intermediate12 min · lesson 3 of 12

A resource is Chef’s declarative building block: a statement of a piece of desired state, with a type, a name, and properties. package, service, template, file, directory, user, execute — each maps to something on the system and knows how to bring it to the declared state on the platform it runs on. A recipe is an ordered collection of resources, and Chef converges them in the order written.

recipes/default.rb
package 'nginx' do
action :install
end
template '/etc/nginx/nginx.conf' do
source 'nginx.conf.erb'
notifies :reload, 'service[nginx]' # only if this file changes
end
service 'nginx' do
action [:enable, :start]
end

Actions, and platform abstraction

Every resource has actions (install/remove, start/stop/enable, create/delete) and a sensible default. The package resource abstracts the platform: the same declaration installs via apt on Debian and yum/dnf on RHEL, because Chef picks the right provider from the node’s detected platform. This is what lets one cookbook target a mixed fleet, and it is why you declare package ‘nginx’ rather than shelling out to a specific package manager.

Reach for a resource before execute
The execute resource runs an arbitrary command and is the Chef equivalent of shell — it is not idempotent unless you guard it. Before using it, check for a real resource (package, service, mount, cron); if you must run a command, add a guard (not_if/only_if or creates) so it fires solely when needed. Undisciplined execute blocks are the top cause of non-idempotent, surprising converges.