Puppet promotes a scheme that is called The roles and profile method. It’s basically an extra layer of abstraction that shields away the technical components, allowing you to focus on the use case of the machine.
- With “profiles” you group together the software components into a technology stack.
- With “roles” you compose your target machine class with those profiles.
Example
A developer workstation computer that may run GNOME by default.
# Role for profiles that need to make a developer machine work
class role::workstation::developer (
$desktop = 'gnome',
) {
# All roles should include the base profile
include profile::base
include profile::authentication::client
include profile::workstation
include "profile::desktop::${desktop}"
include profile::development
}
The base profile configures, e.g., the underlying OS flavor.
# Base profile (includes component modules for all nodes)
class profile::base {
case $::osfamily {
'Debian': {
include unattended_upgrades
package {[
'apt-transport-https',
'aptitude',
'software-properties-common',
'ssh',
'uuid-runtime',
'vim',
]:
ensure => present,
}
service { 'systemd-timesyncd.service':
ensure => running,
enable => true,
flags => '--now',
provider => systemd,
}
}
'RedHat': {
package { 'puppetlabs-release-pc1-el-7':
# enable official Puppet Labs collection repository (old agent otherwise)
ensure => present,
provider => rpm,
source => 'https://yum.puppetlabs.com/puppetlabs-release-pc1-el-7.noarch.rpm',
}
package {[
'openssh-clients',
'openssh-server',
'puppet-agent',
'vim-enhanced',
]:
ensure => present,
}
}
default: {
notify { "Operating system ${::operatingsystem} not supported": }
}
}
package {[
'curl',
'htop',
'nano',
'ncdu',
'sudo',
'tmux',
'tree',
]:
ensure => present,
}
}
The workstation profile configures common settings and software of any PC of this type.
# Workstation base profile (includes component modules for all client PCs)
class profile::workstation {
include software::browsers::chrome
include software::browsers::firefox
include software::communication::matrix
include mycompany::backup::restore
include mycompany::branding
include mycompany::printers
include mycompany::userdefaults
class { 'keyboard':
layout => 'en',
}
class { 'locales':
default_locale => 'en_US.UTF-8',
locales => [
'en_US.UTF-8 UTF-8',
'de_DE.UTF-8 UTF-8',
'it_IT.UTF-8 UTF-8',
],
}
# common packages needed everywhere
package {[
'gimp',
'python-gpgme',
'virtualbox',
]:
ensure => present,
}
}
The desktop role will apparently configure what’s in the (default setup) of GNOME, KDE, etc.
And so forth.
Summary
In essence, this scheme allows to keep a more high-level picture of what use case you’re dealing with when configuring your target system. When the roles are cleanly separated, the composition in a role is a very helpful tool to shape your system.
That’s how it works in Puppet when you do it right. I feel that the typical NixOS configs are too deep into the implementation details. Maybe such a scheme would help to stay more focused. Has anyone ever tried something like this?