Asserting the Existence of External Facts

Facter 1.7 introduced support for external facts, and I gave some external fact examples, but it left a couple of small issues unresolved. One of the larger ones is the subject of syncing the external facts down to the clients.

At the moment most people are managing the external facts as file resources which creates one important difference between an internal and external fact. Internal facts are synced down at the start of the run and so are available to the puppet agent within a single run. External facts (when managed as puppet resources) are synced on the first run and then evaluated and made available to the puppet agent in future runs; which can lead to a very broken initial run. One possible way around this is to pull in an external module, assert by Ben Ford, and use it check that your external facts are available before using them.

file { '/etc/facter/facts.d/external_fact.txt':
  ensure => 'present',
  source => 'puppet:///modules/external_things/external_fact.txt',
}

assert { 'External fact foo must be available':
  condition => $::external_fact,
}
-> class { 'external_things': }

On an initial run the above code sample pulls down the external fact using the file resource and then checks that the fact exists using the assertion. If the fact is absent the assert raises a Puppet::Error, "Assert Failed: " and all the dependent resources are skipped. This does mean you’ll have multiple runs before node convergence but if you’re using external facts you’ll have to handle this one way or another.

It’s also worth noting this issue has been discussed on the Puppet-Dev list under the subject Plugin sync support for external facts and so native support for external fact syncing will be along in a future version.