Puppet practitioner Course - Day 2

Create a new module

Either create directory tree

modules directory structure
modules
- foo-module
|\- manifests
| \-init.pp
| |-class2.pp
|\-examples
| \-init.pp
|\-files
|\-templates
 \-rspec

The modules can then be declared using

include foo-module

  • Note this would need to contain a class called "foo-module"

include foo-module::class2.pp

Exported Resources

Allows resources to be transferred from one node to another. A lot of reasons not to use this (i.e. dangers in this), but as an example, you could export hosts entries so that each system appears in the hosts file on each other system.

All exported resources are tracked by puppetdb

class hosts {
# create a virtual host resource based on known information
# and export it back to the Puppet Master
@@host { $::hostname:
ip => $::ipaddress,
host_aliases => $::fqdn,
}
# collect all exported resources and realize them on this host
Host <<||>>
# ensure that we have no host entries that aren't explicitly configured
resources { 'host':
purge => true,
}

Exported resources are shared across all environments (be careful, as changing a resource value in a test environment on the puppet master will impact anything referencing the exported resource in the production puppet environment).

Custom Facts

Facts live in

modules
- foo-module
\- lib
 \- facts
  |- custom-fact.erb

Facts are distributed using pluginsync
facter -p {fact} will show the fact we have generated.

The ruby file could look like this

# system_uptime.rb
Facter.add('system_uptime') do
  setcode 'uptime | awk -F, "{print $1}"'
end

Note - need to ensure quoting is OK (i.e. can't use single quotes in awk command if using single quotes in setcode)

Use ruby -c uptime/lib/system_uptime.rb to check ruby syntax
Use RUBYLIB="$PWD/uptime/lib" facter uptime to check functionality before committing

Note - facts don't need to be declared, the module doesn't need to be declared in order for the fact to be collected.

Managing files
file_line Resource

Parameters:

  • ensure
  • line
  • name
  • path
  • match

This looks to do the same as sed -i (in-plae editing)

If a line matches the given regex exists, it will replace the line
If no matching line is found, it adds this line at the end of the file.

An error will occur if multiple lines match the given expression. It is kind of limited in what it can do.

Concat module

You can take fragments from multiple sources, including

  • Static files
  • Templates
  • strings

and concatenate them (using a custom sequence) into a destination file.

(need puppet module install puppetlabs/concat)

ini_set

Not covered in the course, but good for managing Windows Ini style files

Augeas

This module is the equivalent to mounting a file as a filesystem (e.g. /etc/puppet.conf), then lets you edit individual elements of the file. Far more effective than a simple sed search/replace (as used in "file_line".

"Lenses" are the providers for augeas. i.e. a sudoers lens defines the grammar, syntax and format of the sudoers file through a series of regex definitions, allowing you to easily leverage this when editing such files.

Augeas is open source, there are plenty of contributors to lenses, chances are a lens already exists for the file you're trying to work with.

Augtool

Useful for 'navigating'a file and visually seeing what augeas can do with it.

[master]root@robbie:~/puppetcode/modules # /opt/puppetlabs/puppet/bin/augtool
augtool> ls /files
etc/ = (none)
root/ = (none)
boot/ = (none)
augtool> ls /files/etc/krb5.conf/
logging/ = (none)
libdefaults/ = (none)
realms/ = (none)
domain_realm/ = (none)
augtool> get /files/etc/krb5.conf/libdefaults/default_realm
/files/etc/krb5.conf/libdefaults/default_realm = EXAMPLE.COM

We can the use this information to create a class to set the default realm for kerberos

class kerberos {
  augeas { 'krb5.conf':
    context => '/files/etc/krb5.conf/libdefaults',
    changes => 'set default_realm PUPPETLABS.VM',
  }
}
Profiles - modules from sourceforge

There is a module called profiles. The idea is to never touch the modules downloaded from puppetforge, instead creating your own profiles. Essentially

  • modules/{module_name}*
  • --> Should always be managed by software updates from puppetforge, never modify the contents (otherwise config will drift and you won't be able to upgrade/patch in future)
    modules
  • modules/profiles/manifests/*
  • --> Managed by you - store all your profile data here.

Set up a class, e.g. profiles::tuned

e.g. modules/profiles/manifests/tuned.pp

class profiles::tuned {
$default_profile = heira ('profile::tuned::default_profile')
$active_profile = heira ('profile::tuned::active_profile')
class {"tuned:
  default_profile = $default_profile
  active_profile = $active_profile
  }
}

Then, the hieradata file contains:

profiles::tuned::default_profile: "high_performance"
profiles::tuned::active_profile: "high_performance"
Hiera Data

Important to separate config-data from code. If we include data in the modules, it can make it really difficult to troubleshoot issues, trace the source of data etc

Hieradata provides the opportunity to separate the configuration data away from the module code

Three categories of data

  • Secret data (e.g. passwords) --> Can be handled using eYAML
  • Org specific data (e.g. IP addresses, user lists, package lists etc) --> Good for hieradata
  • Defaults --> Often best to leave these in params.pp (this is really valuable to leave them here)

hiera_config path is defined in puppet.conf

hiera.yaml file then defines the hierarchy of parameter matching. i.e. if clientcert is listed first, all values in robbie.puppetlabs.yaml (i.e. client cert filename) are accepted in preference before anything else. Normally "defaults" are listed as the lowest preference value

Hieradata nodes directory

Don't necessarily need to keep one clientcert file per node. If a node just has the defaults, the clientcert file isn't required (and will just consume resources).

Where is my value coming from?

hiera -c (yaml) --debug will helpp find the source of values

(and other values)

puppet agent --test --debug | grep hiera may also show you where the values are being derived from

Hiera Array

If you need to concatenate data from multiple levels (e.g. sudoers users for global, plus datacentre specific, plus server specific), hiera array will allow you to achieve this.

Hieradata format

--- at the top of the file - this is part of the YAML standard. Not necessarily needed.
The file will break if you include more than one instance of the triple dashes in the file