fbpx
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

6 Secrets To A Successful Atlassian Migration At Scale

6 Secrets To A Successful Atlassian Migration At Scale

With large scale migrations, large user bases, multiple Atlassian tools, plenty of apps, and lots of data, moving to Atlassian Cloud may feel like a steep mountain to climb. But, it doesn't have to be. In fact, we've already helped many customers make the move. Plus,...

Related Resources

What Is AWS (Amazon Web Services)?

What Is AWS (Amazon Web Services)?

Amazon Web Services (AWS) is one of the three biggest cloud service providers in the market, alongside Microsoft and Google. Additionally, it was one of the first cloud providers when it launched Amazon Elastic Compute Cloud (Amazon EC2) and Amazon Simple Storage...

Scaling Jenkins for the Enterprise

Scaling Jenkins for the Enterprise

I’m Michael Roberts, Vice President for SPK. And I want to tell you the tricks for scaling your business effectively with a Jenkins enterprise solution. I'll also explain how to avoid, and remediate both a Jenkins monolith, and islands of Jenkins. In the early part of...

LastPass Business For Corporate and Client Security

LastPass Business For Corporate and Client Security

At SPK, we want to empower employees to safely manage their own passwords. Additionally, for organizations, we want to enable the enforcement of password standards. Businesses that follow good password standards, such as increased complexity, non-duplicate passwords ...