Do you think IIT Guwahati certified course can help you in your career?
No
Introduction
Puppet Enterprise enables you to comprehend your infrastructure's configuration, including all physical components of your data center, virtualized and cloud infrastructure, and everything running in containers. Puppet maintains the appropriate state automatically while giving you complete authority to make adjustments as your company's needs change, ensuring consistency and keeping you in compliance.
The key-value pair is referred to as "fact" in Puppet. Each resource contains its own set of facts, and users can create their custom facts in puppet. The Facter command can be used to display a list of all the environment variables and their values.
Custom facts in Puppet
Custom facts can be added to the main Puppet server by writing snippets of Rubycode. Puppet then distributes the facts to the client via plug-ins in modules.
Adding custom facts to Facter
You may need to write conditional expressions based on site-specific data that Facter does not provide, or you may want to include it in a template.
Because arbitrary Ruby code cannot be included in manifests, the best solution is to add a new fact to Facter. These extra facts can then be distributed to Puppet clients and used in manifests and templates just like any other fact.
Loading custom facts
Facter offers multiple methods of loading custom facts in puppet.
You can use these methods to test files locally before distributing them or to make a specific set of facts available on specific machines.
Using the Ruby load path
Facter looks for subdirectories named Facter in the Ruby $LOAD PATH variable and loads all Ruby files in those directories. Facter loads facter/users.rb, facter/rackspace.rb, and facter/system load.rb.
Using the --custom-dir command line option
Facter accepts multiple –custom-dir command-line options that specify a single directory to search for custom facts. Facter attempts to load all Ruby files in the directories specified.
$ ls my_facts
system_load.rb
$ ls my_other_facts
users.rb
$ facter --custom-dir=./my_facts --custom-dir=./my_other_facts system_load users
system_load => 0.25
users => thomas,pat
Using the FACTERLIB environment variable
Facter also examines the environment variable FACTERLIB for a delimited (semicolon for Windows, colon for all other platforms) set of directories and attempts to load all Ruby files in those directories.
Facter.add('fact name') is used to determine the name of the fact.
For simple resolutions, a setcode statement that is evaluated to determine the fact's value.
Facts can be much more complicated than that, but those two are the most common ways to implement a custom fact.
Using other facts
Facter.value('somefact') allows you to create a fact that uses other facts. Facter returns nil if the fact cannot be resolved or is not present.
Facter.add('osfamily') do
setcode do
distid = Facter.value('lsbdistid')
case distid
when /RedHatEnterprise|CentOS|Fedora/
'redhat'
when 'ubuntu'
'debian'
else
distid
end
end
end
Configuring facts
You can use the properties of facts to customize how they are evaluated.
Confining facts
The confine statement restricts the fact to only running on systems that match another given fact, which is one of the more commonly used properties.
Fact precedence
A single fact can have multiple resolutions, each of which determines the fact's value differently. It's common, for example, to have different resolutions for different operating systems. You add the fact again with a different setcode statement to add a new resolution to it.
When there are multiple resolutions for a fact, the first resolution that returns a value other than nil determines the fact's value. The weight property describes how Facter decides on the issue of resolution precedence. After Facter eliminates any resolutions ruled out due to confining statements, the resolution with the highest weight is evaluated first. If that resolution returns nil, Facter moves on to the next resolution (in descending order) until it returns nil.
Execution timeouts
Resolution timeouts are supported by Factor 4. Facter prints an error message if the timeout is exceeded. Facter.warn ensures that the message is printed to STDERR when run as a standalone application. Facter.warn prints the message to Puppet's log when called as part of a catalog application. When an exception is not caught, Facter logs it as an error.
Aggregate resolutions
Use aggregate resolutions if your fact combines the output of multiple commands. Each chunk of an aggregate resolution is responsible for resolving one piece of the fact. After each chunk has been resolved independently, it is combined into a single flat or structured fact and returned.
Aggregate resolutions differ from simple resolutions in several ways, beginning with the fact declaration. To introduce an aggregate resolution, add the :type => :aggregate parameter:
Facter.add('fact_name', :type => :aggregate) do
#chunks go here
#aggregate block goes here
end
Each step in the resolution then gets its own named chunk statement:
chunk('one') do
'Chunk one returns this. '
end
chunk('two') do
'Chunk two returns this.'
end
A setcode statement is never used in aggregate resolutions. They have an optional aggregate block that combines the chunks instead. The fact's value is whatever value the aggregate block returns. Here's an example that simply combines the strings from the previous two chunks:
aggregate do |chunks|
result = ' '
chunks.each_value do |str|
result += str
end
# Result: "Chunk one returns this. Chunk two returns this."
result
end
You can skip the aggregate block if all chunk blocks return arrays or hashes. If you do, Facter will combine all of your data into a single array or hash and use that as the value of the fact.
Environment facts
You can use the CLI or the Ruby API to access a fact set with environment variables (Facter.value or Facter.fact methods).
It's worth noting that environment facts are lowercase before being added to the fact collection; for example, FACTER EXAMPLE and FACTER example resolve to a single fact called example.
Writing custom facts in Puppet
In Facter, a typical fact is a collection of several elements that can be written as a simple value like"flat" fact or as structured data ("structured" fact). This page explains how to write and format facts correctly.
Writing custom facts in puppet with simple resolutions
Most facts are resolved all at once, eliminating the need to combine data from multiple sources. In that case, the solution is straightforward. Simple resolutions can be found for both flat and structured facts.
Main components of simple resolutions
Simple facts are typically composed of the following components:
1. A Facter.add(:fact name) call:
This adds a new fact or a new resolution to an existing fact of the same name.
A symbol or a string can be used as the name.
The remainder of the information is contained within the do... end block of the add call.
2. Zero or more confine statements:
Determine whether the resolution is appropriate (and therefore is evaluated).
Can either match another fact's value or evaluate a Ruby block.
A block is required when given a symbol or string representing a fact name, and the fact's value is passed as an argument to the block.
The keys of a hash are expected to be fact names. The hash values are either the expected fact values or an array of values to compare.
If a block is provided, the confine is appropriate only if the block returns any value other than false or nil.
3. Optional has_weight statement:
Multiple resolutions are when available for a fact, and resolutions are ranked from highest to lowest weight value.
It must be a positive integer, i.e., greater than 0.
Number of confined statements for the resolution is the default.
4. Setcode statement that determines the value of the fact
It can accept a string or a block.
Facter executes a string as a shell command when given one. If the command is successful, the command's output is the fact's value. If the command fails, the next appropriate resolution is considered.
If a block is provided, the fact's value is returned unless the block returns nil. If nil is returned, the next appropriate resolution is considered.
The Facter::Core::Execution.exec function can be used to execute shell commands within a setcode block.
Only the last setcode block is used if multiple setcode statements are evaluated for a single resolution.
How to format facts
Good
Bad
Facter.add('phi') do
confine owner: "BTO"
confine :kernel do |value|
value == "Linux"
end
setcode do
bar=Facter.value('theta')
bar + 1
end
end
Facter.add('phi') do
confine owner: "BTO"
confine :kernel do |value|
value == "Linux"
end
bar = Facter.value('theta')
setcode do
bar + 1
end
end
When outside the guarded setcode block and in the unguarded part of the Facter.add block, the Facter.value('theta') call is made. This means that the statement is always executed on every system, regardless of confine, weight, or phi resolution. Any code with potential side effects, or code relating to determining the value of a fact, must be contained within the setcode block. Outside of setcode, the only code left is code that helps Facter decide which resolution of a fact to use.
Writing structured facts
Structured facts can be represented as hashes or arrays. You don't need to do anysuch specific thing to mark the fact as structured; if your fact returns a hash or an array, Facter recognizes it as such. Structured facts can be resolved in simple or aggregate ways.
Writing custom facts in puppet with aggregate resolutions
Aggregate resolutions enable you to divide a fact's resolution into separate chunks. Facter merges hashes or arrays with hashes by default, resulting in a structured fact. Still, you can aggregate the chunks into a flat fact using concatenation, addition, or any other Ruby function.
Main components of aggregate resolutions
Aggregate resolutions differ from simple resolutions: the presence of chunk statements and the absence of a setcode statement. Facter merges hashes or arrays with hashes or arrays if the aggregate block is not present.
It introduces a new fact or a new resolution for an already existing fact of the same name.
A symbol or a string can be used as the name.
For aggregate resolutions, the:type =>:aggregate parameter is required.
The remainder of the information is contained within the do... end block of the add call.
2. Zero or more confine statements:
Determine whether the solution is appropriate and (therefore, is evaluated).
They can either compare the value of one fact to another or evaluate a Ruby block.
A block is required when given a symbol or string representing a fact name, and the fact's value is passed as an argument to the block.
The keys of a hash are expected to be fact names. The hash values are either the expected fact values or an array of values to compare.
If a block is provided, the confine is appropriate if the block returns a value other than nil or false.
3. An optional has_weight statement:
This function evaluates multiple resolutions for a fact from the highest weight value to the lowest.
It must be a positive integer, i.e., greater than zero.
The number of confined statements for the resolution is the default.
4. One or more than one calls to chunk, each containing:
Name (as the argument to chunk).
A piece of code is in charge of converting the chunk to a value. The block returns the chunk's value; it can be of any type but is typically a hash or array.
5. An optional aggregate block:
Facter automatically merges hashes and arrays if they are not present.
To merge the chunks in any other specific way, you must use aggregate, which requires a code block.
The block is given a single argument (in this case, chunks), a hash of chunk name to chunk value for all chunks in the resolution.
External facts in Puppet
External facts enable the use of arbitrary executables or scripts as facts and the setting of facts statically with structured data. You can use this information to create a custom fact in Puppet, Perl, C, or a one-line text file.
Executable facts on Unix
On Unix, executable facts are activated by placing an executable file in the standard external fact path. On Unix, executable facts always require a shebang (#!) The execution of the fact fails if the shebang is missing.
An example external fact written in Python is given below:
#!/usr/bin/env python
data = {"key1" : "value1", "key2" : "value2" }
for k in data:
print "%s=%s" % (k,data[k])
Ensure that the script has set it's execute bit:
chmod +x /etc/facter/facts.d/my_fact_script.py
The script should always return key-value pairs, JSON, or YAML for Facter to parse.
Facter parses data returned by custom executable external facts in YAML or JSON format. Facter returns to parsing the returned value as a key-value pair if it is not YAML.
Executable facts on Windows
On Windows, executable facts are activated by placing an executable file in the external fact path. According to the external facts interface, Windows scripts should end with a known extension. Lines can end with either LF or CRLF. The extensions listed below are supported:
.exe and .com: binary executables
.cmd and .bat: batch scripts, and
.ps1: PowerShell scripts
The script should always return key-value pairs, JSON, or YAML. Facter parses data returned by custom executable external facts in YAML or JSON format. Facter falls back to parsing the returned value as a key-value pair if it is not YAML.
Executable fact locations
Using pluginsync, you can distribute external executable facts. Place external executable facts in MODULEPATH>/MODULE>/facts.d/ to add them to your Puppet modules.
External facts must be placed in a standard directory if you are not using pluginsync. This directory's location varies depending on your operating system, whether you're using Puppet Enterprise or open source releases, or running as root or Administrator. With the —external-dir option, you can specify the external facts directory when calling Facter from the command line.
In a module(preferred):
<MODULEPATH>/<MODULE>/facts.d/
On Linux, Unix, or Mac OS X, there are three directories mentioned:
When running as a non-Administrator or non-root user:
<HOME DIRECTORY>/.facter/facts.d/
Troubleshooting
If your external fact does not appear in Facter's output, running Facter in debug mode can help you figure out why and which file is causing the issue:
# puppet facts --debug
If an external fact doesn't match what you have configured in your facts.d directory, check to see if you have defined the same fact using the stdlib module's external facts capabilities.
Drawbacks
External facts, while providing a mostly-equal way to create variables for Puppet, have a few drawbacks:
An external fact cannot be used to refer to another fact. Due to parsing order, you can reference an external fact from a Ruby fact.
External executable facts are forked rather than executed concurrently.
Frequently Asked Questions
What exactly is a Puppet fact?
The key-value pair is referred to as "fact" in Puppet. Each resource has its own set of facts, and the users can create their custom facts in puppet The Facter command can be used to list all of the environment variables and their values.
Where can you find Puppet facts?
Run facter -p on the command line to see a node's fact values or browse facts on node detail pages in the Puppet Enterprise console.
In Puppet, how are variables like $Operatingsystem set?
Facter controls all of the variables. Running a facter in a shell will give you a complete list of the available variables and their values.
What exactly is the Facter command?
Facter is a command-line tool that collects basic information about nodes (systems), such as hardware specifications, network settings, operating system type and version, and more.
In Puppet, how do you make a custom fact?
Custom facts in Puppet can be added to the main server by writing snippets of Ruby code. Puppet then distributes the facts to the client via plug-ins in modules. See Module plug-in types for information on how to add custom facts to modules.
Conclusion
We have now learned what custom facts are in puppets and how to add and write them on windows and Unix operating systems. We also went through some external facts on windows and Unix and learned about their location and how to troubleshoot them. Check out this problem - First Missing Positive