There are several design patterns used in Puppet code. One is not typically better than another, but each brings a degree of complexity. Choose the design pattern that makes sense for your specific use case in your component module. Keep things simple, and add complexity only where it is needed. Puppet is great about layers of abstraction and being able to get as complex as needed, but that doesn’t mean we have to.
params.pp
pattern
The params.pp
design pattern is great for when you need to calculate default values based on more complex criteria. For most default parameters, you can use module-level Hiera to pass OS-specific default parameters in. This pattern allows the params.pp
class to be inherited by the main class to set those reasonable defaults using inheritance. You can reference documentation here on parameter defaults.
Install, config, service pattern
This pattern is becoming commonplace, but it is only a design pattern. If your module doesn’t have all these functions, then this pattern does not make sense, but most things do require installation, configuration, and a service to manage.
Using this pattern has a main class that contains all the parameters and then small sub classes that focus on the one area of focus, install, config, and service. The main class uses a function called class containment to include the sub classes in the specific ordering required. For a good reference on this pattern, please reference the puppetlabs-ntp
module.
Roles and profiles
Roles and profiles has been featured in this video when the concept was introduced at PuppetConf 2016. This design pattern has quickly become the best practice for implementing Puppet Code due to the additional layers of abstraction and focusing customization at the profile layer. The roles and profiles pattern allows for great flexibility in your automation journey and you can assemble components as needed.
Profiles
Our best practices for profiles can be found here. Profiles are the implementation and customization layer for your component modules. If your profile doesn’t set a parameter for a component module, then it should be using the module defaults. Hiera data gets plugged into profiles and should not be directly to the component module. An old but still relevant document on roles and profiles can be found here..
Roles
Our best practices for roles can be found here. Roles should be named more toward the business logic or business use case of the node instead of the technology used to create it. For example, a log server may be role::logserver
even though it uses profile::splunk::server
. Roles should not include any parameters or Puppet code other than includes of your profiles. An old but still relevant document on roles and profiles can be found here.
Examples
Profile
class profile::jenkins (
Integer $jenkins_port,
) {
class { 'jenkins':
executors => 0,
port => $jenkins_port,
}
}
Role
class role::buildmaster {
include profile:jenkins
include profile:baseline
}
Comments
0 comments
Please sign in to leave a comment.