A virtual resource declaration specifies a desired state for a resource without adding it to the catalog. You can then add the resource to the catalog by realizing it elsewhere in your manifests. This splits the work done by a normal resource declaration into two steps.
Although virtual resources can only be declared once, they can be realized any number of times (much as a class may be included
multiple times).
Virtual resources are useful for:
Virtual resources can be used in some of the same situations as classes, since they both offer a safe way to add a resource to the catalog in more than one place. The features that distinguish virtual resources are:
Virtual resources are used in two steps: declaring and realizing.
# <modulepath>/apache/manifests/init.pp
...
# Declare:
@a2mod { 'rewrite':
ensure => present,
} # note: The a2mod type is from the puppetlabs-apache module.
# <modulepath>/wordpress/manifests/init.pp
...
# Realize:
realize A2mod['rewrite']
# <modulepath>/freight/manifests/init.pp
...
# Realize again:
realize A2mod['rewrite']
In the example above, the apache
class declares a virtual resource, and both the wordpress
and freight
classes realize it. The resource will be managed on any node that has the wordpress
and/or freight
classes applied to it.
To declare a virtual resource, prepend @
(the “at” sign) to the type of a normal resource declaration:
@user {'deploy':
uid => 2004,
comment => 'Deployment User',
group => www-data,
groups => ["enterprise"],
tag => [deploy, web],
}
realize
FunctionTo realize one or more virtual resources by title, use the realize
function, which accepts one or more resource references:
realize User['deploy'], User['zleslie']
The realize
function may be used multiple times on the same virtual resource and the resource will only be added to the catalog once.
Any resource collector will realize any virtual resource that matches its search expression:
User <| tag == web |>
You can use multiple resource collectors that match a given virtual resource and it will only be added to the catalog once.
Note that a collector used in an override block or a chaining statement will also realize any matching virtual resources.
By itself, a virtual resource declaration will not add any resources to the catalog. Instead, it makes the virtual resource available to the compiler, which may or may not realize it. A matching resource collector or a call to the realize
function will cause the compiler to add the resource to the catalog.
Virtual resources do not depend on parse order. You may realize a virtual resource before the resource has been declared.
realize
FunctionThe realize
function will cause a compilation failure if you attempt to realize a virtual resource that has not been declared. Resource collectors will fail silently if they do not match any resources.
If a virtual resource is contained in a class, it cannot be realized unless the class is declared at some point during the compilation. A common pattern is to declare a class full of virtual resources and then use a collector to choose the set of resources you need:
include virtual::users
User <| groups == admin or group == wheel |>
You may declare virtual resources of defined resource types. This will cause every resource contained in the defined resource to behave virtually — they will not be added to the catalog unless the defined resource is realized.
Virtual resources will be evaluated in the run stage in which they are declared, not the run stage in which they are realized.