Exported resources

An exported resource declaration specifies a desired state for a resource, and publishes the resource for use by other nodes. It does not manage the resource on the target system. Any node, including the node that exports it, can collect the exported resource and manage its own copy of it.

Purpose

Exported resources enable the Puppet compiler to share information among nodes by combining information from multiple nodes’ catalogs. This helps manage things that rely on nodes knowing the states or activity of other nodes.

Note: Exported resources rely on the compiler accessing the information, and can not use information that’s never sent to the compiler, such as the contents of arbitrary files on a node.
The common use cases are monitoring and backups. A class that manages a service like PostgreSQL, exports a nagios_service resource which describes how to monitor the service, including information such as its hostname and port. The Nagios server collects every nagios_service resource, and automatically starts monitoring the Postgres server.
Note: Exported resources require catalog storage and searching (storeconfigs) enabled on your primary Puppet server. Both the catalog storage and the searchin, among other features, are provided by PuppetDB. To enable exported resources, see:

Syntax

Using exported resources requires two steps: declaring and collecting. In the following examples, every node with the ssh class exports its own SSH host key and then collects the SSH host key of every node (including its own). This causes every node in the site to trust SSH connections from every other node.

class ssh {
  # Declare:
  @@sshkey { $::hostname:
    type => dsa,
    key  => $::sshdsakey,
  }
  # Collect:
  Sshkey <<| |>>
		   }
To declare an exported resource, prepend @@ to the resource type of a standard resource declaration:
@@nagios_service { "check_zfs${::hostname}":
  use                 => 'generic-service',
  host_name           => $::fqdn,
  check_command       => 'check_nrpe_1arg!check_zfs',
  service_description => "check_zfs${::hostname}",
  target              => '/etc/nagios3/conf.d/nagios_service.cfg',
  notify              => Service[$nagios::params::nagios_service],
}
To collect exported resources, use an exported resource collector. Collect all exported nagios_service resources:
Nagios_service <<| |>> 
This example, taken from puppetlabs-bacula, which uses the ripienaar-concat module, collects exported file fragments for building a Bacula config file:
Concat::Fragment <<| tag == "bacula-storage-dir-${bacula_director}" |>>
Tip: It's difficult to predict the title of an exported resource, because any node could be exporting it. It’s best to search on a more general attribute, and this is one of the main use cases for tags.

For more information on the collector syntax and search expressions, see Exported resource collectors.

Behavior

When catalog storage and searching (storeconfigs) are enabled, the primary server sends a copy of every compiled catalog to PuppetDB. PuppetDB retains the recent catalog for every node and provides the server with a search interface to each catalog.

Declaring an exported resource adds the resource to the catalog marked with an exported flag. Unless it was collected, this prevents the agent from managing the resource. When PuppetDB receives the catalog, it takes note of this flag.

Collecting an exported resource causes the primary server to send a search query to PuppetDB. PuppetDB responds with every exported resource that matches the search expression, and the server adds those resources to the catalog.

An exported resource becomes available to other nodes as soon as PuppetDB finishes storing the catalog that contains it. This is a multi-step process and might not happen immediately. The primary server must have compiled a given node’s catalog at least one time before its resources become available. When the primary server submits a catalog to PuppetDB, it is added to a queue and stored as soon as possible. Depending on the PuppetDB server’s workload, there might be a delay between a node’s catalog being compiled and its resources becoming available.

Normally, exported resource types include their default attribute values. However, defined types are evaluated for the catalog after the resource is collected, so their default values are not exported. To make sure a defined type's values are exported, set them explicitly.

To remove stale exported resources, expire or deactive the node that exported them. This ensures that any resources exported by that node stop appearing in the catalogs served to the remaining agent nodes. For details, see the documentation for deactivating or expiring nodes.

CAUTION: Each exported resource must be globally unique across every single node. If two nodes export resources with the same title or same name/namevar, the compilation fails when you attempt to collect both. Some pre-1.0 versions of PuppetDB do not fail in this case. To ensure uniqueness, every resource you export must include a substring unique to the node exporting it into its title and name/namevar. The most expedient way is to use the hostname or fqdn facts.
Restriction: Exported resource collectors do not collect normal or virtual resources. They cannot retrieve non-exported resources from other nodes’ catalogs.
The following example shows Puppet native types for managing Nagios configuration files. These types become powerful when you export and collect them.

For example, to create a class for Apache that adds a service definition on your Nagios host, automatically monitoring the web server:

/etc/puppetlabs/puppet/modules/nagios/manifests/target/apache.pp:
class nagios::target::apache {
  @@nagios_host { $::fqdn:
    ensure  => present,
    alias   => $::hostname,
    address => $::ipaddress,
    use     => 'generic-host',
  }
  @@nagios_service { "check_ping_${::hostname}":
    check_command       => 'check_ping!100.0,20%!500.0,60%',
    use                 => 'generic-service',
    host_name           => $::fqdn,
    notification_period => '24x7',
    service_description => "${::hostname}_check_ping"
  }
}
/etc/puppetlabs/puppet/modules/nagios/manifests/monitor.pp:
class nagios::monitor {
  package { [ 'nagios', 'nagios-plugins' ]: ensure => installed, }
  service { 'nagios':
    ensure     => running,
    enable     => true,
    #subscribe => File[$nagios_cfgdir],
    require    => Package['nagios'],
  }
Collect resources and populate /etc/nagios/nagios_*.cfg:
 Nagios_host <<||>>
  Nagios_service <<||>>