🧩 Definitions
Definitions let you group multiple resources into a reusable, parameterized block – similar to a lightweight custom resource.
📝 Defining a Definition
Use the define keyword at the top level of a recipe:
define :install_and_enable_package, version: nil do
v = params[:version]
package params[:name] do
version v if v
action :install
end
service params[:name] do
action :enable
end
end
Parameters:
- First argument: the definition name (as a Symbol)
- Keyword arguments: parameter names with default values
- Block: the resource declarations
Inside the block, params is a hash containing:
:name– the resource name passed when using the definition- Any keyword parameters you declared
▶️ Using a Definition
Once defined, use it like any other resource:
install_and_enable_package 'nginx' do
version '1.6.1'
end
install_and_enable_package 'redis'
A
definemust appear before it is used in the recipe. Define it at the top of the file or in an included recipe.
📖 Practical Examples
🚀 Application deployment pattern
define :deploy_app, user: 'deploy', port: 3000 do
directory "/opt/#{params[:name]}" do
owner params[:user]
end
git "/opt/#{params[:name]}" do
repository "https://github.com/org/#{params[:name]}.git"
revision 'main'
end
template "/etc/systemd/system/#{params[:name]}.service" do
source 'app.service.erb'
variables(
name: params[:name],
user: params[:user],
port: params[:port]
)
notifies :run, "execute[systemctl daemon-reload]"
end
end
execute 'systemctl daemon-reload' do
action :nothing
end
deploy_app 'web-api' do
port 4000
end
deploy_app 'worker'
🔀 Conditional package installation
define :install_if_missing do
execute "install #{params[:name]}" do
command "apt-get install -y #{params[:name]}"
not_if "dpkg -l #{params[:name]} | grep -q ^ii"
end
end
install_if_missing 'htop'
install_if_missing 'jq'
⚖️ Definitions vs. Resource Plugins
| Feature | Definitions | Resource Plugins |
|---|---|---|
| Complexity | Simple | More involved |
| Distribution | Inline in recipes | Gem-based |
| Reuse scope | Within the project | Across projects |
| Custom logic | Limited | Full Ruby class |
Use definitions for project-specific abstractions. Use resource plugins when you need to share resources across projects.