External facts provide a way to use arbitrary executables or scripts as facts, or set facts statically with structured data. With this information, you can write a custom fact in Perl, C, or a one-line text file.
Executable facts on Unix
Executable facts on Unix work by dropping an executable file into the standard external fact path. A shebang (#!
) is always required for executable facts on Unix. If the shebang is missing, the execution of the fact fails.
An example external fact written in Python:
data = {"key1" : "value1", "key2" : "value2" }
for k in data:
print "%s=%s" % (k,data[k])
You must ensure that the script has its execute bit set:
chmod +x /etc/facter/facts.d/my_fact_script.py
For
Facter to parse the output, the script must return key-value pairs on STDOUT in the format:
key1=value1
key2=value2
key3=value3
Using this format, a single script can return multiple facts.
Executable facts on Windows
Executable facts on
Windows work by dropping an executable file into the external fact path. Unlike with
Unix, the external facts interface expects
Windows scripts to end with a known extension. Line endings can be either
LF
or
CRLF
. The following extensions are supported:
As with
Unix facts, each script must return key-value pairs on STDOUT in the format:
key1=value1
key2=value2
key3=value3
Using this format, a single script can return multiple facts in one return.
For batch scripts, the file encoding for the .bat
or .cmd
files must be ANSI or UTF8 without BOM, or you get strange output.
Here is a sample batch script which outputs facts using the required format:
@echo off
echo key1=val1
echo key2=val2
echo key3=val3
REM Invalid - echo 'key4=val4'
REM Invalid - echo "key5=val5"
For PowerShell scripts, the encoding used with .ps1
files is flexible. PowerShell determines the encoding of the file at run time.
Here is a sample
PowerShell script which outputs facts using the required format:
Write-Host "key1=val1"
Write-Host 'key2=val2'
Write-Host key3=val3
Save and execute this
PowerShell script on the command line.
Executable fact locations
Distribute external executable facts with pluginsync. To add external executable facts to your Puppet modules, place them in <MODULEPATH>/<MODULE>/facts.d/
.
If you’re not using pluginsync, then external facts must go in a standard directory. The location of this directory varies depending on your operating system, whether your deployment uses Puppet Enterprise or open source releases, and whether you are running as root or Administrator. When calling Facter from the command line, you can specify the external facts directory with the --external-dir
option.
Note: These directories don’t necessarily exist by default; you might need to create them. If you create the directory, make sure to restrict access so that only administrators can write to the directory.
In a module (recommended):
<MODULEPATH>/<MODULE>/facts.d/
On
Unix,
Linux, or
Mac OS X, there are three directories:
/opt/puppetlabs/facter/facts.d/
/etc/puppetlabs/facter/facts.d/
/etc/facter/facts.d/
On
Windows:
C:\ProgramData\PuppetLabs\facter\facts.d\
When running as a non-root or non-Administrator user:
<HOME DIRECTORY>/.facter/facts.d/
Note: You can use custom facts as a non-root user only if you have first
configured non-root user access and previously run
Puppet agent as that same user.
Structured data facts
Facter can parse structured data files stored in the external facts directory and set facts based on their contents.
Structured data files must use one of the supported data types and must have the correct file extension.
Facter supports the following extensions and data types:
.yaml
: YAML data, in the following format:
---
key1: val1
key2: val2
key3: val3
.json
: JSON data, in the following format:
{ "key1": "val1", "key2": "val2", "key3": "val3" }
.txt
: Key-value pairs, of the
String
data type, in the following format:
key1=value1
key2=value2
key3=value3
As with executable facts, structured data files can set multiple facts at one time.
{
"datacenter":
{
"location": "bfs",
"workload": "Web Development Pipeline",
"contact": "Blackbird"
},
"provision":
{
"birth": "2017-01-01 14:23:34",
"user": "alex"
}
}
Structured data facts on Windows
All of the above types are supported on Windows with the following notes:
Troubleshooting
If your external fact is not appearing in
Facter’s output, running
Facter in debug mode can reveal why and tell you which file is causing the problem:
One possible cause is a fact that returns invalid characters. For example if you used a hyphen instead of an equals sign in your script
test.sh
:
#!/bin/bash
echo "key1-value1"
Running
puppet facts --debug
yields the following message:
...
Debug: Facter: resolving facts from executable file "/tmp/test.sh".
Debug: Facter: executing command: /tmp/test.sh
Debug: Facter: key1-value1
Debug: Facter: ignoring line in output: key1-value1
Debug: Facter: process exited with status code 0.
Debug: Facter: completed resolving facts from executable file "/tmp/test.sh".
...
If you find that an external fact does not match what you have configured in your facts.d
directory, make sure you have not defined the same fact using the external facts capabilities found in the stdlib
module.
Drawbacks
While external facts provide a mostly-equal way to create variables for
Puppet, they have a few drawbacks:
An external fact cannot internally reference another fact. However, due to parse order, you can reference an external fact from a Ruby fact.
External executable facts are forked instead of executed within the same process.