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.