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 simplified form of a resource declaration includes:

  • The resource type, which is a lowercase word with no quotes, such as file.

  • 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 (}).

You can use any amount of whitespace in the Puppet language.

This example declares a file resource with the title /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

By creating more complex resource declarations, you can:

  • 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 complete generalized form of a resource declaration expression is:
  • 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], or Resource['file']. It must have a type but not a resource reference.

  • 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.

This example declares several different files, all using the default values set in the 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.

The value of the splat (*) 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.

This sets values for that resource's attributes, using every attribute and value listed in the hash.

For example, the splat attribute in this declaration sets the owner, group, and mode settings for the file resource.

$file_ownership = {
  "owner" => "root",
  "group" => "wheel",
  "mode"  => "0644",
}

file { "/etc/passwd":
  ensure => file,
  *      => $file_ownership,
}

You cannot set any attribute more than once for a given resource; if you try, Puppet raises a compilation error. This means that:

  • 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 set mode => "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 use some attributes from a hash and override others, either use a hash to set per-expression defaults, as described in the Resource declaration default attributes section (above), or use the merging operator, + to combine attributes from two hashes, with the right-hand hash overriding the left-hand one.

Abstract resource types

Because a resource declaration can accept a resource type data type as its resource type , you can use a 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.

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.

For example:

$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 a 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 Setting attributes from a hash section (above).

To amend attributes with a resource reference, add a resource reference attribute block to the resource that's already declared. Normally, you can only use resource reference blocks to add previously unmanaged attributes to a resource; it cannot override already-specified attributes. The general form of a resource reference attribute block is:

  • A resource reference to the resource in question

  • An opening curly brace

  • Any number of attribute => value pairs

  • A closing curly brace

For example, this resource reference attribute block amends values for the 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.

The general form of a collector attribute block is:

  • 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

For resource attributes that accept multiple values in an array, such as the relationship metaparameters, you can add to the existing values instead of replacing them by using the "plusignment" (+>) keyword instead of the usual hash rocket (=>). For details, see appending to attributes in the classes documentation.

This example amends the 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',
}

Be very careful when amending attributes with a collector. Test with --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.

This example defines defaults in a $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,
    ;
  }
}