Docs: Language: Virtual Resources


Language: Virtual Resources

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

Purpose

Virtual resources are useful for:

  • Resources whose management depends on at least one of multiple conditions being met
  • Overlapping sets of resources which may be required by any number of classes
  • Resources which should only be managed if multiple cross-class conditions are met

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:

  • Searchability via resource collectors, which lets you realize overlapping clumps of virtual resources
  • Flatness, such that you can declare a virtual resource and realize it a few lines later without having to clutter your modules with many single-resource classes

For more details, see Virtual Resource Design Patterns.

Syntax

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.

Declaring a Virtual Resource

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],
    }

Realizing With the realize Function

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

Realizing With a Collector

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.

Behavior

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.

Parse-Order Independence

Virtual resources do not depend on parse order. You may realize a virtual resource before the resource has been declared.

Collectors vs. the realize Function

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

Virtual Resources in Classes

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

Defined Resource Types

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.

↑ Back to top