External facts
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.
#!/usr/bin/env 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 should return key-value pairs, JSON, or YAML.
Custom executable external facts can return data in YAML or JSON format, and Facter parses it into a structured fact. If the returned value is not YAML, Facter falls back to parsing it as a key-value pair.
By using the key-value pairs on STDOUT format, a single script can return multiple facts:
key1=value1
key2=value2
key3=value3
Executable facts on Windows
LF
or CRLF
. The
following extensions are supported: -
.com
and.exe
: binary executables -
.bat
and.cmd
: batch scripts -
.ps1
: PowerShell scripts
The script should return key-value pairs, JSON, or YAML.
Custom executable external facts can return data in YAML or JSON format, and Facter parses it into a structured fact. If the returned value is not YAML, Facter falls back to parsing it as a key-value pair.
By using the key-value pairs on STDOUT format, a single script can return multiple facts:
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.
@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.
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.
<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/
Structured data facts
Facter can parse structured data files stored in the external facts directory and set facts based on their contents.
-
.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 theString
data type, in the following format:key1=value1 key2=value2 key3=value3
{
"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:
-
The line endings can be either
LF
orCRLF
. -
The file encoding must be either ANSI or UTF8 without BOM.
Troubleshooting
# puppet facts --debug
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
-
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.