Implementing the Roles and Profiles pattern

Hiera is a great tool to take control of the behavior of modules for your different agents. Most Puppet setups rely on many Forge modules to implement all the required management solutions. It is a common challenge to find efficient ways of structuring the local code.

A very successful and widespread design pattern to this end was conceived by Craig Dunn and is called the Roles and Profiles pattern. It defines two layers of abstraction. The outer layer is made of roles, which are defined in a way that allows for each server (or workstation) to choose exactly one role. There is no mixing—if a node has aspects of two different roles, then this merger forms a new role itself. Examples for roles can be internal_webserver, key_distribution_center, or accounting_desktop.

Technically, a role is just a class. It is sensible to organize your roles in a role module:

node 'falstaff.example.net' {
  include role::key_distribution_center
}

Do limit each node block to include just one role class. There should be no further include statements and no resource declarations. Variable declarations will be acceptable, but Hiera is almost universally preferred.

As for roles, they should comprise nothing but the inclusion of one or more profile classes. Profiles quite distinctly represent aspects of a system. In the server realm, typical profiles would be apache_server, nginx_proxy, postgres_server, or ldap_master. Just like roles, profiles should be organized in a dedicated module:

class role::key_distribution_center {
  include profile::heimdal_server
  include profile::firewall_internal
}

Profiles themselves will ideally just include a selection of modules with data from Hiera. In a profile class, it might also be acceptable to pass some module parameters directly in the manifest. A profile can consistently configure some of its required modules this way, without the need for possible redundancy in the Hiera data of all the nodes that use this profile.

This is risky, though, because profiles can become incompatible or even impose subtle evaluation-order dependencies. Having a Hiera layer is cleaner, as it selects data sources through each node's role. At this layer, you can cleanly express configuration that should be effective for all nodes that fill this role:

# role/key_distribution_center.yaml
heimdal::default_realm: EXAMPLE.NET
heimdal::kdcs:
  - kdc01.example.net
  - kdc02.example.net
  - admin.example.net

These heimdal module parameters are used indirectly through the heimdal_server profile:

class profile::heimdal_server {
  include heimdal
  class { 'ssh': restricted => true }
}

The following diagram summarizes the pattern:

Implementing the Roles and Profiles pattern

This is just a very rough sketch of the principles behind the Roles and Profiles pattern. Craig has put up a comprehensive description on his blog at http://www.craigdunn.org/2012/05/239/, and the design has since been adopted by many users.

When setting up your first larger Puppet installation, it is a good idea to adhere to the pattern from day one, because it will allow you to scale your manifests without getting tangled up in complicated structures.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.219.103.183