Resources are the fundamental unit for modeling system configurations. Each resource describes the desired state for some aspect of a system, like a specific service or package. When Puppet applies a catalog to the target system, it manages every resource in the catalog, ensuring the the actual state matches the desired state.
Resources contained in classes and defined types share the relationships of those classes and defined types. Resources are not subject to scope: a resource in any area of code can be referenced from any other area of code.
A resource declaration adds a resource to the catalog and tells Puppet to manage that resource's state.
Reads the actual state of the resource on the target system.
Compares the actual state to the desired state.
If necessary, changes the system to enforce the desired state.
Logs any changes made to the resource. These changes appear in Puppet agent's log and in the run report, which is sent to the master and forwarded to any specified report processors.
If the catalog doesn't contain a particular resource, Puppet does nothing with whatever that resource described. If you remove a package resource from your manifests, Puppet doesn't uninstall the package; instead, it just ignores it. To remove a package, manage it as a resource and set ensure => absent
.
You can delay adding resources to the catalog. For example, classes and defined types can contain groups of resources. These resources are managed only if you add that class or defined resource to the catalog. Virtual resources are added to the catalog only after they are realized.
Resource declarations
<TYPE> { '<TITLE>': <ATTRIBUTE> => <VALUE>, }
The resource title and attributes are called the resource body. A resource declaration can have one resource body or multiple resource bodies of the same resource type.
Resource declarations are expressions in the Puppet language — they always have a side effect of adding a resource to the catalog, but they also resolve to a value.The value of a resource declaration is an array of resource references, with one reference for each resource the expression describes.
A resource declaration has extremely low precedence; in fact, it's even lower than the variable assignment operator (=
). This means that if you use a resource declaration for its value, you must surround it with parentheses to associate it with the expression that uses the value.
They all have the same resource type.
They can all draw from the same pool of default values, if a resource body with the title
default
is present.
Resource uniqueness
Each resource must be unique; Puppet does not allow you to declare the same resource twice. This is to prevent multiple conflicting values from being declared for the same attribute. Puppet uses the resource title
and the name
attribute or namevar to identify duplicate resources — if either the title or the name is duplicated within a given resource type, catalog compilation fails. See the page about resource syntax for details about resource titles and namevars. To provide the same resource for multiple classes, use a class or a virtual resource to add it to the catalog in multiple places without duplicating it. See classes and virtual resources for more information.
Relationships and ordering
By default, Puppet applies unrelated resources in the order in which they're written in the manifest. If a resource must be applied before or after some other resource, declare a relationship between them to show that their order isn't coincidental. You can also make changes in one resource cause a refresh of some other resource. See the Relationships and ordering page for more information.
Otherwise, you can customize the default order in which Puppet applies resources with the ordering setting. See the configuration page for details about this setting.
Resource types
Every resource is associated with a resource type, which determines the kind of configuration it manages. Puppet has built-in resource types such as file
, service
, and package
. See the resource type reference for a complete list and information about the built-in resource types.
Defined types are lightweight resource types written in the Puppet language.
Custom resource types are written in Ruby and have the same capabilities as Puppet's built-in types.
Title
/etc/passwd
: file { '/etc/passwd':
owner => 'root',
group => 'root',
}
Titles must be unique per resource type. You can have both a package and a service titled "ntp," but you can only have one service titled "ntp." Duplicate titles cause compilation to fail.
The title of a resource differs from the namevar of the resource. Whereas the title identifies the resource to Puppet itself, the namevar identifies the resource to the target system and is usually specified by the resource's name
attribute. The resource title doesn't have to match the namevar, but you'll often want it to: the value of the namevar attribute defaults to the title, so using the name in the title can save you some typing.
If a resource type has multiple namevars, the type specifies whether and how the title maps to those namevars. For example, the package
type uses the provider
attribute to help determine uniqueness, but that attribute has no special relationship with the title. See each type's documentation for details about how it maps title to namevars.
Attributes
Attributes describe the desired state of the resource; each attribute handles some aspect of the resource.For example, the file
type has a mode
attribute that specifies the permissions for the file.
Each resource type has its own set of available attributes; see the resource type reference for a complete list. Most resource types have a handful of crucial attributes and a larger number of optional ones.Attributes accept certain data types, such as strings, numbers, hashes, or arrays. Each attribute that you declare must have a value. Most attributes are optional, which means they have a default value, so you do not have to assign a value. If an attribute has no default, it is considered required, and you must assign it a value.
Most resource types contain an ensure
attribute. This attribute generally manages the most basic state of the resource on the target system, such as whether a file exists, whether a service is running or stopped, or whether a package is installed or uninstalled.The values accepted for the ensure
attribute vary by resource type. Most accept present
and absent
, but there are variations. Check the reference for each resource type you are working with.
Namevars and name
Every resource on a target system must have a unique identity; you cannot have two services, for example, with the same name. This identifying attribute in Puppet is known as the namevar.
Each resource type has an attribute that is designated to serve as the namevar. For most resource types, this is the name
attribute, but some types use other attributes, such as the file
type, which uses path
, the file's location on disk, for its namevar. If a type's namevar is an attribute other than name
, this is listed in the type reference documentation.
Most types have only one namevar. With a single namevar, the value must be unique per resource type. There are a few rare exceptions to this rule, such as the exec
type, where the namevar is a command. However, some resource types, such as package
, have multiple namevar attributes that create a composite namevar. For example, both the yum
provider and the gem
provider have mysql
packages, so both the name
and the provider
attributes are namevars, and Puppet uses both to identify the resource.
The namevar differs from the resource's title, which identifies a resource to Puppet's compiler rather than to the target system. In practice, however, a resource's namevar and the title are often the same, because the namevar usually defaults to the title. If you don't specify a value for a resource's namevar when you declare the resource, Puppet uses the resource's title.
You might want to specify different a namevar that is different from the title when you want a consistently titled resource to manage something that has different names on different platforms. For example, the NTP service might be ntpd
on Red Hat systems, but ntp
on Debian and Ubuntu. You might title the service "ntp," but set its namevar --- the name
attribute --- according to the operating system. Other resources can then form relationships to the resource without the title changing.
Metaparameters
Some attributes in Puppet can be used with every resource type. These are called metaparameters. These don't map directly to system state. Instead, metaparameters affect Puppet's behavior, usually specifying the way in which resources relate to each other.
The most commonly used metaparameters are for specifying order relationships between resources. See the documentation on relationships and ordering for details about those metaparameters. See the full list of available metaparameters in the metaparameter reference.
Resource syntax
You can accomplish a lot with just a few resource declaration features, or you can create more complex declarations that do more.
Basic syntax
The resource type, which is a word with no quotes.
An opening curly brace
{
.The title, which is a string.
A colon (
:
).Optionally, any number of attribute and value pairs, each of which consists of:
An attribute name, which is a lowercase word with no quotes.
A
=>
(called an arrow, "fat comma," or "hash rocket").A value, which can have any [data type][datatype].
A trailing comma.
A closing curly brace (
}
).
/etc/passwd
. This declaration's ensure
attribute ensures that the specified file is created, if it does not already exist on the node. The rest of the declaration sets values for the file's owner
, group
, and mode
attributes. file { '/etc/passwd':
ensure => file,
owner => 'root',
group => 'root',
mode => '0600',
}
Complete syntax
Describe many resources at once.
Set a group of attributes from a hash with the
*
attribute.Set default attributes.
Specify an abstract resource type.
Amend or override attributes after a resource is already declared.
The resource type, which can be one of:
A lowercase word with no quotes, such as
file
.A resource type data type, such as
File
,Resource[File]
, orResource['file']
. It must have a type but not a title.
An opening curly brace (
{
).One or more resource bodies, separated with semicolons (
;
). Each resource body consists of:A title, which can be one of:
A string.
An array of strings, which declares multiple resources.
The special value
default
, which sets default attribute values for other resource bodies in the same expression.
A colon (
:
).Optionally, any number of attribute and value pairs, separated with commas (
,
). Each attribute/value pair consists of:An attribute name, which can be one of:
A lowercase word with no quotes.
The special attribute
*
, called a "splat," which takes a hash and sets other attributes.A
=>
, called an arrow, a "fat comma," or a "hash rocket".A value, which can have any data type.
Optionally, a trailing comma after the last attribute/value pair.
Optionally, a trailing semicolon after the last resource body.
A closing curly brace (
}
)
<TYPE> { default: * => <HASH OF ATTRIBUTE/VALUE PAIRS>, <ATTRIBUTE> => <VALUE>, ; '<TITLE>': * => <HASH OF ATTRIBUTE/VALUE PAIRS>, <ATTRIBUTE> => <VALUE>, ; '<NEXT TITLE>': ... ; ['<TITLE'>, '<TITLE>', '<TITLE>']: ... ;
Resource declaration default attributes
If a resource declaration includes a resource body with a title of default
, Puppet doesn't create a new resource named "default." Instead, every other resource in that declaration uses attribute values from the default
body if it doesn't have an explicit value for one of those attributes. This is also known as "per-expression defaults."
Resource declaration defaults are useful because it lets you set many attributes at once, but you can still override some of them.
default
resource body. However, the mode
value for the the files in the last array (['ssh_config', 'ssh_host_dsa_key.pub'....
) is set explicitly instead of using the default. file {
default:
ensure => file,
owner => "root",
group => "wheel",
mode => "0600",
;
['ssh_host_dsa_key', 'ssh_host_key', 'ssh_host_rsa_key']:
# use all defaults
;
['ssh_config', 'ssh_host_dsa_key.pub', 'ssh_host_key.pub', 'ssh_host_rsa_key.pub', 'sshd_config']:
# override mode
mode => "0644",
;
}
The position of the default
body in a resource declaration doesn't matter; resources above and below it all use the default attributes if applicable.You can only have one default
resource body per resource declaration.
Setting attributes from a hash
You can set attributes for a resource by using the splat attribute, which uses the splat or asterisk character *
, in the resource body.
*
) attribute must be a hash where: Each key is the name of a valid attribute for that resource type, as a string.
Each value is a valid value for the attribute it's assigned to.
owner
, group
, and mode
settings for the file resource.$file_ownership = {
"owner" => "root",
"group" => "wheel",
"mode" => "0644",
}
file { "/etc/passwd":
ensure => file,
* => $file_ownership,
}
If you use a hash to set attributes for a resource, you cannot set a different, explicit value for any of those attributes. For example, if
mode
is present in the hash, you can't also setmode => "0644"
in that resource body.You can't use the
*
attribute multiple times in one resource body, since the splat itself is an attribute.
+
to combine attributes from two hashes, with the right-hand hash overriding the left-hand one. Abstract resource types
Resource[<TYPE>]
value to specify a non-literal resource type, where the <TYPE>
portion can be read from a variable.That is, the following three examples are equivalent to each other: file { "/tmp/foo": ensure => file, } File { "/tmp/foo": ensure => file, } Resource[File] { "/tmp/foo": ensure => file, }
$mytype = File
Resource[$mytype] { "/tmp/foo": ensure => file, }
$mytypename = "file"
Resource[$mytypename] { "/tmp/foo": ensure => file, }
This lets you declare resources without knowing in advance what type of resources they'll be, which can enable transformations of data into resources. For a demonstration, see the `create_resources` example below. Arrays of titles
If you specify an array of strings as the title of a resource body, Puppet creates multiple resources with the same set of attributes. This is useful when you have many resources that are nearly identical.
$rc_dirs = [
'/etc/rc.d', '/etc/rc.d/init.d','/etc/rc.d/rc0.d',
'/etc/rc.d/rc1.d', '/etc/rc.d/rc2.d', '/etc/rc.d/rc3.d',
'/etc/rc.d/rc4.d', '/etc/rc.d/rc5.d', '/etc/rc.d/rc6.d',
]
file { $rc_dirs:
ensure => directory,
owner => 'root',
group => 'root',
mode => '0755',
}
If you do this, you must let the namevar attributes of these resources default to their titles. You can't specify an explicit value for the namevar, because it applies to all of the resources. Adding or modifying attributes
Although you cannot declare the same resource twice, you can add attributes to an resource that has already been declared. In certain circumstances, you can also override attributes. You can amend attributes with either a resource reference, a collector, or from a hash using the splat (*
) attribute.
To amend attributes with the splat attribute, see the section about setting attributes from a hash.
A resource reference to the resource in question
An opening curly brace
Any number of attribute
=>
value pairsA closing curly brace
owner
, group
, and mode
attributes: file {'/etc/passwd':
ensure => file,
}
File['/etc/passwd'] {
owner => 'root',
group => 'root',
mode => '0640',
}
You can also amend attributes with a collector.
A resource collector that matches any number of resources
An opening curly brace
Any number of attribute => value (or attribute +> value) pairs
A closing curly brace
+>
) keyword instead of the usual hash rocket (=>
). For details, see appending to attributes in the classes documentation.owner
, group
, and mode
attributes of any resources that match the collector:class base::linux {
file {'/etc/passwd':
ensure => file,
}
...}
include base::linux
File <| tag == 'base::linux' |> {
owner => 'root',
group => 'root',
mode => '0640',
}
--noop
to see what changes your code would make. It can override other attributes you've already specified, regardless of class inheritance.
It can affect large numbers of resources at one time.
It implicitly realizes any virtual resources the collector matches.
Because it ignores class inheritance, it can override the same attribute more than one time, which results in an evaluation order race where the last override wins.
Local resource defaults
Because resource default statements are subject to dynamic scope, you can't always tell what areas of code will be affected. Generally, do not include classic resource default statements anywhere other than in your site manifest (site.pp
). See the resource defaults
documentation for details. Whenever possible, use resource declaration defaults, also known as per-expression defaults.
However, resource default statements can be powerful, allowing you to set important defaults, such as file permissions, across resources. Setting local resource defaults is a way to protect your classes and defined types from accidentally inheriting defaults from classic resource default statements.
To set local resource defaults, define your defaults in a variable and re-use them in multiple places, by combining resource declaration defaults and setting attributes from a hash.
$file_defaults
variable, and then includes the variable in a resource declaration default with a hash. class mymodule::params {
$file_defaults = {
mode => "0644",
owner => "root",
group => "root",
}
# ...
}
class mymodule inherits mymodule::params {
file { default: *=> $mymodule::params::file_defaults;
"/etc/myconfig":
ensure => file,
;
}
}