Concept of Facter and Facts in Puppet

Last updated on May 27 2022
Sarika Tak

Table of Contents

Concept of Facter and Facts in Puppet

Puppet – Facter & Facts

Puppet supports holding multiple values as an environment variable. This feature is supported in Puppet by using facter. In Puppet, facter is a standalone tool that holds the environment level variable. In can be considered similar to env variable of Bash or Linux. Sometimes there can be an overlap between the information stored in facts and environment variable of the machine. In Puppet, the key-value pair is known as “fact”. Each resource has its own facts and in Puppet the user has the leverage to build their own custom facts.

# facter

Facter command can be used to list all the different environment variables and its associated values. These collection of facts comes with facter out-of-the-box and are referred to as core facts. One can add custom facts to the collection.

If one wants to view only one variable. It can be done using the following command.

# facter {Variable Name}

 

Example

[root@puppetmaster ~]# facter virtual

virtualbox

The reason why facter is important for Puppet is that facter and facts are available throughout Puppet code as “global variable”, which means it can be used in the code at any point of time without any other reference.

Example to Test

[root@puppetmaster modules]# tree brcle_account

brcle_account

└── manifests  └── init.pp [root@puppetmaster modules]# cat brcle_account/manifests/init.pp

class brcle_account {

user { ‘G01063908’:

ensure => ‘present’,

uid => ‘121’,

shell => ‘/bin/bash’,

home => ‘/home/G01063908’,

}

 

file {‘/tmp/userfile.txt’:

ensure => file,

content => “the value for the ‘OperatingSystem’ fact is: $OperatingSystem \n”,

}

}

Testing It

[root@puppetmaster modules]# puppet agent –test

Notice: /Stage[main]/Activemq::Service/Service[activemq]/ensure:

ensure changed ‘stopped’ to ‘running’

Info: /Stage[main]/Activemq::Service/Service[activemq]:

Unscheduling refresh on Service[activemq]

 

Notice: Finished catalog run in 4.09 seconds

[root@puppetmaster modules]# cat /tmp/testfile.txt

the value for the ‘OperatingSystem’ fact is: Linux

 

[root@puppetmaster modules]# facter OperatingSystem

Linux

As we can notice in the above code snippet, we haven’t defined the OperatingSystem. We have just replaced the value with soft coded value $OperatingSystem as normal variable.

In Puppet, there are three types of fact that can be used and defined −

  • Core Facts
  • Custom Facts
  • External Facts

Core facts are defined at the top level and accessible to all at any point in the code.

Puppet Facts

Just before an agent requests for a catalog from the master, the agent first compiles a complete list of information available in itself in the form of a key value pair. The information on the agent is gathered by a tool called facter and each key-value pair is referred as a fact. Following is a common output of facts on an agent.

[root@puppetagent1 ~]# facter

architecture => x86_64

augeasversion => 1.0.0

bios_release_date => 13/09/2012

bios_vendor => innotek GmbH

bios_version => VirtualBox

blockdevice_sda_model => VBOX HARDDISK

blockdevice_sda_size => 22020587520

blockdevice_sda_vendor => ATA

blockdevice_sr0_model => CD-ROM

blockdevice_sr0_size => 1073741312

blockdevice_sr0_vendor => VBOX

blockdevices => sda,sr0

boardmanufacturer => Oracle Corporation

boardproductname => VirtualBox

boardserialnumber => 0

 

domain => codingbee.dyndns.org

facterversion => 2.1.0

filesystems => ext4,iso9660

fqdn => puppetagent1.codingbee.dyndns.org

hardwareisa => x86_64

hardwaremodel => x86_64

hostname => puppetagent1

id => root

interfaces => eth0,lo

ipaddress => 172.228.24.01

ipaddress_eth0 => 172.228.24.01

ipaddress_lo => 127.0.0.1

is_virtual => true

kernel => Linux

kernelmajversion => 2.6

kernelrelease => 2.6.32-431.23.3.el6.x86_64

kernelversion => 2.6.32

lsbdistcodename => Final

lsbdistdescription => CentOS release 6.5 (Final)

lsbdistid => CentOS

lsbdistrelease => 6.5

lsbmajdistrelease => 6

lsbrelease => :base-4.0-amd64:base-4.0-noarch:core-4.0-amd64:core-4.0noarch:graphics-4.0-amd64:

graphics-4.0-noarch:printing-4.0-amd64:printing-4.0noarch

macaddress => 05:00:22:47:H9:77

macaddress_eth0 => 05:00:22:47:H9:77

manufacturer => innotek GmbH

memoryfree => 125.86 GB

memoryfree_mb => 805.86

memorysize => 500 GB

memorysize_mb => 996.14

mtu_eth0 => 1500

mtu_lo => 16436

netmask => 255.255.255.0

netmask_eth0 => 255.255.255.0

 

network_lo => 127.0.0.0

operatingsystem => CentOS

operatingsystemmajrelease => 6

operatingsystemrelease => 6.5

osfamily => RedHat

partitions => {“sda1″=>{

“uuid”=>”d74a4fa8-0883-4873-8db0-b09d91e2ee8d”, “size” =>”1024000″,

“mount” => “/boot”, “filesystem” => “ext4”}, “sda2″=>{“size” => “41981952”,

“filesystem” => “LVM2_member”}

}

path => /usr/lib64/qt3.3/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin

physicalprocessorcount => 1

processor0 => Intel(R) Core(TM) i7 CPU         920  @ 2.67GHz

processor1 => Intel(R) Core(TM) i7 CPU         920  @ 2.67GHz

processor2 => Intel(R) Core(TM) i7 CPU         920  @ 2.67GHz

processorcount => 3

productname => VirtualBox

ps => ps -ef

puppetversion => 3.6.2

rubysitedir => /usr/lib/ruby/site_ruby/1.8

rubyversion => 1.8.7

selinux => true

selinux_config_mode => enforcing

selinux_config_policy => targeted

selinux_current_mode => enforcing

selinux_enforced => true

selinux_policyversion => 24

serialnumber => 0

sshdsakey => AAAAB3NzaC1kc3MAAACBAK5fYwRM3UtOs8zBCtRTjuHLw56p94X/E0UZBZwFR3q7

WH0x5+MNsjfmdCxKvpY/WlIIUcFJzvlfjXm4qDaTYalbzSZJMT266njNbw5WwLJcJ74KdW92ds76pjgm

CsjAh+R9YnyKCEE35GsYjGH7whw0gl/rZVrjvWYKQDOmJA2dAAAAFQCoYABgjpv3EkTWgjLIMnxA0Gfud

QAAAIBM4U6/nerfn6Qvt43FC2iybvwVo8ufixJl5YSEhs92uzsW6jiw68aaZ32q095/gEqYzeF7a2knr

OpASgO9xXqStYKg8ExWQVaVGFTR1NwqhZvz0oRSbrN3h3tHgknoKETRAg/imZQ2P6tppAoQZ8wpuLrXU

CyhgJGZ04Phv8hinAAAAIBN4xaycuK0mdH/YdcgcLiSn8cjgtiETVzDYa+jF

swapfree => 3.55 GB

swapfree_mb => 2015.99

swapsize => 3.55 GB

swapsize_mb => 2015.99

timezone => GMT

type => Other

uniqueid => a8c0af01

uptime => 45:012 hours

uptime_days => 0

uptime_hours => 6

uptime_seconds => 21865

uuid => BD8B9D85-1BFD-4015-A633-BF71D9A6A741

virtual => virtualbox

In the above code, we can see some of the data overlap with few of the information available in bash “env” variable. Puppet directly does not use the data, instead it makes use of facter data, Facter data is treated as global variable.

The facts are then available as top level variable and the Puppet master can use them to compile the Puppet catalog for the requesting agent. Facters are called in manifest as normal variable with $ prefix.

Example

if ($OperatingSystem == “Linux”) {

$message = “This machine OS is of the type $OperatingSystem \n”

} else {

$message = “This machine is unknown \n”

}

 

file { “/tmp/machineOperatingSystem.txt”:

ensure => file,

content => “$message”

}

The above manifest file only bothers about a single file called machineOperatingSystem.txt, where the content of this file is deducted by the fact called OperatingSystem.

[root@puppetagent1 /]# facter OperatingSystem

Linux

 

[root@puppetagent1 /]# puppet apply /tmp/ostype.pp

Notice: Compiled catalog for puppetagent1.codingbee.dyndns.org

in environment production in 0.07 seconds

Notice: /Stage[main]/Main/File[/tmp/machineOperatingSystem.txt]/ensure:

defined content as ‘{md5}f59dc5797d5402b1122c28c6da54d073’

Notice: Finished catalog run in 0.04 seconds

 

[root@puppetagent1 /]# cat /tmp/machinetype.txt

This machine OS is of the type Linux

Custom Facts

All the above facts that we have seen are the core facts of the machine. One can add this custom facts to the node in the following ways −

  • Using the “export FACTER … Syntax”
  • Using the $LOAD_PATH settings
  • FACTERLIB
  • Pluginsync

Using the “export FACTER” Syntax

One can manually add the facts using the export FACTER_{fact’s name} syntax.

Example

[root@puppetagent1 facter]# export FACTER_tallest_mountain=”Everest”

[root@puppetagent1 facter]# facter tallest_mountain Everest

Using the $LOAD_PATH Settings

In Ruby, $LOAD_PATH is equivalent to Bash special parameter. Although it is similar to bash $PATH variable, in real facts $LOAD_PATH is not an environment variable, instead it is a pre-defined variable.

$LOAD_PATH has a synonym “$:”. This variable is an array to search and load the values.

[root@puppetagent1 ~]# ruby -e ‘puts $LOAD_PATH’

# note you have to use single quotes.

/usr/lib/ruby/site_ruby/1.6

/usr/lib64/ruby/site_ruby/1.6

/usr/lib64/ruby/site_ruby/1.6/x86_64-linux

/usr/lib/ruby/site_ruby

/usr/lib64/ruby/site_ruby

/usr/lib64/site_ruby/1.6

/usr/lib64/site_ruby/1.6/x86_64-linux

/usr/lib64/site_ruby

/usr/lib/ruby/1.6

/usr/lib64/ruby/1.6

/usr/lib64/ruby/1.6/x86_64-linux

Let’s take an example of creating a directory facter and adding a .pp file and appending a content to it.

[root@puppetagent1 ~]# cd /usr/lib/ruby/site_ruby/

[root@puppetagent1 site_ruby]# mkdir facter

[root@puppetagent1 site_ruby]# cd facter/

[root@puppetagent1 facter]# ls

[root@puppetagent1 facter]# touch newadded_facts.rb

Add the following content to the custom_facts.rb file.

[root@puppetagent1 facter]# cat newadded_facts.rb

Facter.add(‘tallest_mountain’) do

setcode “echo Everest”

end

Facter works in the method of scanning through all the folder listed in $LOAD_PATH, and looks for a director called facter. Once it finds that particular folder, it will load them anywhere in the folder structure. If it finds this folder then it looks for any Ruby file in that facter folder and loads all the defined facts about any particular configuration in the memory.

Using FACTERLIB

In Puppet, FACTERLIB works very much similar to $LOAD_PATH but with only one key difference that, it is a OS level environment parameter rather than a Ruby special variable. By default, the environment variable may not be set.

[root@puppetagent1 facter]# env | grep “FACTERLIB”

[root@puppetagent1 facter]#

To test FACTERLIB, we need to perform the following steps.

Create a folder called test_facts in the following structure.

[root@puppetagent1 tmp]# tree /tmp/test_facts/

/tmp/some_facts/

├── vipin

│   └── longest_river.rb

└── testing

└── longest_wall.rb

Add the following contents to the .rb files.

[root@puppetagent1 vipin]# cat longest_river.rb

Facter.add(‘longest_river’) do

setcode “echo Nile”

end

 

[root@puppetagent1 testing]# cat longest_wall.rb

Facter.add(‘longest_wall’) do

setcode “echo ‘China Wall'”

end

Use the export statement.

[root@puppetagent1 /]# export

FACTERLIB = “/tmp/some_facts/river:/tmp/some_facts/wall”

[root@puppetagent1 /]# env | grep “FACTERLIB”

FACTERLIB = /tmp/some_facts/river:/tmp/some_facts/wall

Test the new facter.

[root@puppetagent1 /]# facter longest_river

Nile

[root@puppetagent1 /]# facter longest_wall

China Wall

External Facts

External facts are very useful when the user wishes to apply some new facts created at the provisioning time. External facts are one of the key ways of applying metadata to a VM at its provisioning stage (e.g. using vSphere, OpenStack, AWS, etc.)

All the metadata and its details created can be used by Puppet to determine what details should be present in the catalog, which is going to be applied.

Creating an External Fact

On the agent machine, we need to create a directory as mentioned below.

$ mkdir -p /etc/facter/facts.d

Create a Shell script in the directory with the following content.

$ ls -l /etc/facter/facts.d

total 4

-rwxrwxrwx. 1 root root 65 Sep 18 13:11 external-factstest.sh

$ cat /etc/facter/facts.d/external-factstest.sh

#!/bin/bash

echo “hostgroup = dev”

echo “environment = development”

Change the permission of the script file.

$ chmod u+x /etc/facter/facts.d/external-facts.sh

Once done, we can now see the variable present with the key/value pair.

$ facter hostgroup

dev

$ facter environment

development

One can write custom facts in Puppet. As a reference, use the following link from the Puppet site.

https://docs.puppet.com/facter/latest/fact_overview.html#writing-structured-facts

 

So, this brings us to the end of blog. This Tecklearn ‘Concept of Facter and Facts in Puppet’ blog helps you with commonly asked questions if you are looking out for a job in DevOps. If you wish to learn Puppet and build a career in DevOps domain, then check out our interactive, Continuous Deployment: Configuration Management using Puppet Training, that comes with 24*7 support to guide you throughout your learning period. Please find the link for course details:

https://www.tecklearn.com/course/continuous-deployment-configuration-management-using-puppet/

Continuous Deployment: Configuration Management using Puppet Training

About the Course

Tecklearn has specially designed this Continuous Deployment: Configuration Management using Puppet Training Course to advance your skills for a successful career in this domain. The course will cover different components of Git and GitHub and how they are used in software development operations. The course consists of Configuration Management using Puppet, Puppet Components, important concepts like Puppet Lifecycle, Puppet Language and Puppet Installation. You will get an in-depth knowledge of these concepts and will be able to work on related demos. Upon completion of this online training, you will hold a solid understanding and hands-on experience with Puppet.

Why Should you take Configuration Management using Puppet Training?

  • Average salary of Puppet Professional is $90k – Payscale.com
  • Uber, Salesforce, PayPal, Booking.com, MIT, Starbucks. & many other MNC’s worldwide use Puppet across industries.
  • According to Grand View Research, the DevOps market size is estimated to be worth $12.85 billion by 2025. DevOps professionals are highly paid and in-demand throughout industries including retail, eCommerce, finance, and technology.

What you will Learn in this Course?

Introduction to DevOps

  • What is Software Development
  • Software Development Life Cycle
  • Why DevOps?
  • What is DevOps?
  • DevOps Lifecycle
  • DevOps Tools
  • Benefits of DevOps
  • How DevOps is related to Agile Delivery
  • DevOps Implementation

Continuous Deployment: Configuration Management using Puppet

  • Need of Configuration Management
  • What is Puppet
  • Puppet Architecture
  • Puppet Components
  • Puppet Lifecycle
  • Setting up Master Slave using Puppet
  • Puppet Manifests
  • Puppet Modules
  • Applying configuration using Puppet
  • Puppet File Server
  • Hands On

 

 

0 responses on "Concept of Facter and Facts in Puppet"

Leave a Message

Your email address will not be published. Required fields are marked *