Product SiteDocumentation Site

8.3. Virtual Resources

Using virtual resources is a way to avoid duplicate definitions in your manifests if you define a virtual resource in parent classes, inherit the parent classes in sub-classes, and realize() the virtual resource in the sub-class.
An example where you can use virtual resources is a webserver class:
class webserver {
    package { "httpd":
        ensure => installed
    }

    class ssl {
        package { [
                "httpd",
                "mod_ssl"
            ]:
            ensure => installed
        }
    }
}
Now, if you were to include webserver on a system, everything is well. However, some other class may require the webserver::ssl class to be applied to the system as well:
class mail {
    class server {
        # Include webserver::ssl for secure webmail capacity
        include webserver::ssl

        webserver::virtualhost { "mail.$domain":
            enable => true,
            certificate => true
        }

        package { "squirrelmail":
            ensure => installed
        }
    }
}
This would result in a duplicate definition of the Package["httpd"] resource. Such is easily prevented by making sure the Package["httpd"] resource is only defined once:
class webserver {
    @package { [
            "httpd",
            "mod_ssl"
        ]:
        ensure => installed
    }

    realize(Package["httpd"])

    class ssl inherits webserver {
        realize(    Package["httpd"],
                    Package["mod_ssl"])
    }
}
To declare a package to be a virtual resource, one would place a @ in front of the keyword package. Then, in the class where the virtual resource is realized, one would call the realize() function on the resource, as above in the example.
A more complex but also more appropriate example can be found at http://git.puppetmanaged.org/?p=puppet;a=blob;f=manifests/init.pp. Note that in the puppet module linked from puppetmanaged.org, the definition and use of virtual resources is a necessity.