Parameterized Puppet class
Continuing my experimentation with Puppet I created my first class which takes parameters and sets those parameters using data in the master repository (for now).
Shortly after my initial post, I added a class called my_user
to the profiles
module to create and manage my user’s account on machines I manage. The first version looked like this:
class profiles::my_user {
user {
'my_login':
ensure => present,
comment => 'My Full Name',
managehome => true,
password => Sensitive('encrypted password'),
purge_ssh_keys => true,
shell => '/bin/bash'
}
}
There are number of drawbacks to hard-coding the values like this - one of which is that my username, password and shell are not the same on all machines. Parameterizing these values make the class flexible for all of my use-cases (I specified default values for most):
class profiles::my_user (
String $username = 'my_login',
Sensitive $password = undef,
String $shell = '/bin/zsh',
Boolean $manage_shell = true
) {
$shell_pkg = $shell ? {
'/bin/bash' => 'bash',
'/bin/zsh' => 'zsh'
}
if ( $manage_shell == true ) {
package { $shell_pkg: }
}
user {
$username:
ensure => present,
comment => 'My Full Name',
managehome => true,
password => $password,
purge_ssh_keys => true,
shell => $shell,
require => Package[$shell_pkg]
}
}
I choose to use the manage_
pattern, as opposed to detecting if the package is already required elsewhere, as this is recommended as the most common pattern used in the Puppet community. There are ways to detect if it is already specified and depend on it if not or ensure_packages
from the stdlib
module (however there are some interesting edgecases for ensure_packages
).
Values for the parameters can be provided directly when using the module or via the hiera
data system. In my previous post I did an initial configuration of hiera.yaml
, and no modification of this configuration was needed.
In the process of moving these values into the data, I also replaced the pattern matching to attach classes in manifests/site.pp
with this that uses the list in the classes
key from the hiera data (this is now the sole content of site.pp
):
hiera_include(classes)
In the data/common.yaml
file goes the data that applies to all nodes (for now the password is here since I am only managing 2 VMs to test):
---
classes:
- profiles::base
profiles::my_user::password: 'encrypted password'
lookup_options:
profiles::my_user::password:
convert_to: "Sensitive"
And in data/nodes/<node.fqdn.dom>.yaml
node-specific data:
---
classes:
- profiles::my_user
- profiles::singularity
As, at present, I only have 2 VMs which are identical in terms of what puppet applies (they are running different operating systems) I simply created a symlink to the first’s node-specific data file for the second. There are techniques for using Puppet’s facts (such as facts.whereami
and facts.group
in the example) to select the data but I have not looked into this further yet.