1-888-310-4540 (main) / 1-888-707-6150 (support) info@spkaa.com
Select Page

Creating “Custom” Facts in Puppet

Published by SPK Blog Post
on August 29, 2017

The servers that I’m managing can be divided into two groups, colo and local servers. While most of the configuration has been similar between these two, there have been a growing number of things which I’ve had to configure differently through Puppet.

The latest example of this is with the time daemon. Local servers needed to have ntp installed, and colo servers needed to have ptp installed.

When I tried to implement these different installations, a small error in the Puppet code caused a subset of colo servers to be seen as local servers, so they ended up having ntp installed and configured instead of ptp.

Part of the reason this error occurred is that the logic for determining if a server is local or not is in my Puppet manifest code, which has become large and unruly. This would have been easily avoidable if the logic didn’t have to be programmed directly in my Puppet manifest file. This led me to think, what if I could make a custom fact that would simply say whether or not a server was a colo server of a local server? This would greatly simplify the code in my manifests.

Turns out that this customization is possible and such a thing is called an external fact and not a custom fact, which is slightly different (This is why “custom” is in quotes in the title. Puppet has custom and external facts, and while the two are similar they are not exactly the same thing.)

External facts are just scripts which return text in the form fact=value. The first part was creating the script, the second part was testing that the script correctly returned the fact, the third part was getting it installed on all servers, and the final part was using the fact in a Puppet manifest.

 

1. Creating the script

This is the bash script I created to return a new fact that I named “location.” It makes use of another fact available out-of-the-box called “ipaddress.”

#!/bin/bash
IP=`facter ipaddress`
if [[ $IP == “10.123”* ]]; then
location=local
elif [[ $IP == “10.157”* ]]; then
location=local
elif [[ $IP == “192.168.120”* ]]; then
location=local
elif [[ $IP == “192.168.150”* ]]; then
location=colo
elif [[ $IP == “192.168.190”* ]]; then
location=colo
elif [[ $IP == “10.147.150”* ]]; then
location=colo
else
location=unknown
fi
echo location=$location

When this script is run, it will print one of the following:

location=local
location=colo
location=unknown

 

2. Testing the external fact

I copied my script to hthe /var/lib/puppet facts.d directory.

If this were an out-of-the-box fact, the following two commands could be used to test that it’s working correctly:

facter location
facter | grep location

but neither one of those came up with anything.

That didn’t mean that Puppet wouldn’t recognize the fact. The syntax just had to be changed a little for facter to recognize it.

The key is to tell facter where to find this external fact by using the –external-dir option. The following two commands both confirmed that the fact was available:

facter –external-dir=/var/lib/puppet/facts.d location
facter –external-dir=/var/lib/puppet/facts.d | grep location

Furthermore, there is a third test which can be run to know if Puppet itself recognizes the fact:

puppet apply -e “notice($::location)”

Running that command confirmed that Puppet would be able to recognize my fact.

After those tests succeeded, I copied them to several different servers and confirmed that they returned the expected results.

 

3.Distributing the fact

In order to use this fact for all servers, it’s not enough to just copy it to the Puppet master server, all the client servers have to have it. In order for Puppet to automatically distribute the fact to all clients, it will have to be installed in the directory <Puppet Module Directory>/<Module>/facts.d on the Puppet master server, and when the puppet clients pull from the server, pluginsync works in the background to transfer the script to the correct directory on the client.

So I created the directory /etc/puppet/modules/facts/facts.d and copied my script there.

I ran “puppet agent -t” on a client server, pluginsync found my file on the puppet master server, and copied it to the directory /var/lib/puppet/facts.d on the client machine.

I then ran the aforementioned test commands and all three tests passed.

 

4. Using the fact

I could now simplify the code in Puppet since I no longer had to program in the logic of determining whether or not a server was at a colo or not, all I had to do was reference the fact.

Basically my puppet code would simplify to:

if $location == ‘colo’ {
            # run these commands
} elsif $location == ‘local’ {
            # run these other commands
}

Latest White Papers

Three Trends Are Transforming The Service Desk

Three Trends Are Transforming The Service Desk

Your IT service desk is about to change. Find out what's shaping the future. Three factors — enterprise service management (ESM), collaboration, and intelligent service management — are driving the transformation of the service desk. To better meet customers’ needs...

Related Resources

Is The IT Department Really “Dead?”

Is The IT Department Really “Dead?”

“It’s Time to Get Rid of the IT Department.”  That was the title of an opinion piece recently published in the Wall Street Journal.  Provocative?  Sure.  My answer to this is not “yes,” but many of the author’s points are valid.  The Same Old IT Department? No, the IT...

How To Add More Disk Space To Your Redhat Server Without Reformatting

How To Add More Disk Space To Your Redhat Server Without Reformatting

(Originally published in 2012, updated January 2022.) One of the common tasks for any system administrator is managing disk space on a server. A common question is how to increase disk space on a linux system. I won't go into a boring lecture on why managing disk...

January 2022 vCAD feature updates

January 2022 vCAD feature updates

Happy New Year vCAD Users! It was a busy 2021 in terms of vCAD development and feature enhancements. We've been receiving lots of feedback regarding the platform, and we're assembling a roadmap for 2022 based on our users' needs. Here's what to expect in 2022:...