The definitions feature in Chef Infra has been deprecated and will be removed in a future release. Please migrate existing definitions to Custom Resources.
This guide describes how to migrate from an existing Definition to a Custom Resource.
If you are creating a Custom Resource from scratch please see the Custom Resource Getting Started Guide instead.
A definition behaved like a compile-time macro that was reusable across recipes. A definition was typically created by wrapping arbitrary code around Chef Infra resources that were declared as if they were in a recipe. A definition was then used in one (or more) actual recipes as if the definition were a resource.
Though a definition looks like a resource, and at first glance seems like it could be used interchangeably, some important differences exist.
Definitions:
notifies, compile_time, subscribes, only_if, not_if, and sensitive
why-run modeA definition had four components:
nil
The basic syntax of a definition was:
define :my_definition_name do
body
end
More commonly, the usage incorporated arguments to the definition:
define :my_definition_name, parameter: :argument, parameter: :argument do
body(likely referencing the params hash)
end
The following simple example shows a definition with no arguments (a parameter-less macro in the truest sense):
define :prime_myfile do
file '/etc/myfile' do
content 'some content'
end
end
An example showing the use of parameters, with a parameter named port that defaults to 4000 rendered into a template resource, would look like:
define :prime_myfile, port: 4000 do
template '/etc/myfile' do
source 'myfile.erb'
variables({
port: params[:port],
})
end
end
Or the following definition, which looks like a resource when used in a recipe, but also contained directory and file resources that were repeated, but with slightly different parameters:
define :host_porter, port: 4000, hostname: nil do
params[:hostname] ||= params[:name]
directory '/etc/#{params[:hostname]}' do
recursive true
end
file '/etc/#{params[:hostname]}/#{params[:port]}' do
content 'some content'
end
end
which was then used in a recipe like this:
host_porter node['hostname'] do
port 4000
end
host_porter 'www1' do
port 4001
end
We highly recommend migrating existing definitions to custom resources to unlock the full feature set of Chef Infra resources. The following example shows a definition and that same definition rewritten as a custom resource.
The following definition processes unique hostnames and ports, passed on as parameters:
define :host_porter, port: 4000, hostname: nil do
params[:hostname] ||= params[:name]
directory '/etc/#{params[:hostname]}' do
recursive true
end
file '/etc/#{params[:hostname]}/#{params[:port]}' do
content 'some content'
end
end
The definition is improved by rewriting it as a custom resource. This uses properties to accept input and has a single :create action:
property :port, Integer, default: 4000
property :hostname, String, name_property: true
action :create do
directory "/etc/#{hostname}" do
recursive true
end
file "/etc/#{hostname}/#{port}" do
content 'some content'
end
end
Once written, a custom resource may be used in a recipe just like any resource that is built into Chef Infra. A custom resource gets its name from the cookbook and the name of its file in the /resources directory with an underscore (_) separating them. For example, a cookbook named host with a custom resource file named porter.rb in the /resources directory would be called host_porter. Use it in a recipe like this:
host_porter node['hostname'] do
port 4000
end
or:
host_porter 'www1' do
port 4001
end
© Chef Software, Inc.
Licensed under the Creative Commons Attribution 3.0 Unported License.
The Chef™ Mark and Chef Logo are either registered trademarks/service marks or trademarks/servicemarks of Chef, in the United States and other countries and are used with Chef Inc's permission.
We are not affiliated with, endorsed or sponsored by Chef Inc.
https://docs.chef.io/definitions_to_custom_resources/