Customize the ordered steps Puppet pattern with hiera values

Customize the ordered steps Puppet pattern with hiera values Do you want to make your team’s Puppet code easier to read and more concise, and better organized? While still allowing customizations to allow the code to fit every client team’s unique needs? Then using the easy_type::ordered_steps function is the way to go.

Introduction

The ordered steps Puppet pattern we introduced in our last blog post helps you write more manageable Puppet code. However, if the sequence of steps needs to support many different clients who all need slightly different behavior, then your streamlined code becomes quickly littered with if-statements and case statements.

This blog post introduces the easy_type::orderd_steps function that allows for customizations to your flow by setting hiera values.

What is the problem?

In our previous blog post, we used this example:

class oracle_database {
  contain systl
  contain os_users_and_groups
  contain limits
  contain packages
  contain oracle_software
  contain database
  contain database_users
  contain database_storage

  Class['systl']
  -> Class['os_users_and_groups']
  -> Class['limits']
  -> Class['packages']
  -> Class['oracle_software']
  -> Class['database']
  -> Class['database_users']
  -> Class['database_storage']
  -> Class['database ']
}

What if your infrastructure team supports many client teams that all have their own ways of doing Puppet things? All just slightly different. Let’s say one of your customer teams has all of the OS limits in the base profile and doesn’t want any other profile modules to handle them. Another team has special requirements for creating the OS users and groups. Yet another team wants to install some extra security software before generating the database. You could use if-statements, but doing so would turn your once elegant class into a monstrosity.

What if you could leave the puppet code for this profile exactly as it is, allowing clients to modify it with hiera values? You certainly can!

Introducing the orderd_steps function

The basic change consists of this code:

easy_type::ordered_steps([
  'systl',
  'os_users_and_groups',
  'limits',
  'packages',
  'oracle_software',
  'database',
  'database_users',
  'database_storage']
)

The Puppet code above uses the easy_type::ordered_steps function with an array of strings. Every string in the array is the name of a puppet class. All these classes will be executed in the order specified- the same as the original code.

This is a little more compact than the previous version, but it’s not much different. And what does this do for customization?

How to customize the behavior?

The ordered_steps function is quite powerful under the hood. Let’s look at some scenarios to illustrate its power.

Skipping a step

In the example above, we discussed a team that doesn’t want any profile classes to go over their security parameters. We can create a new profile class and remove the limits class from the manifest, or we could utilize an if-statement to fix this; however, the ordered_steps function allows you to specify a hiera value that will skip applying this class all together. When you add this to the hiera data for this team:

oracle_database::limits:		skip

the ordered_steps function will skip adding the limits class to your manifest. Thus implementing this use case.

Replacing a step

In the second use case, a team has unique requirements for creating OS users and groups. The current os_users_and_groups class does not align with these preferences. Instead of adding this to the company-wide Puppet code, you would rather have the customer team manage it.

When you include this code:

oracle_database::os_users_and_groups:   customer_team_1::special_os_users_and_groups

in the hiera data for this team, instead of the standard class, the ordered_steps function will call the class supplied by the customer team. As a result, this use case is implemented.

Executing Puppet statements before or after

The final use case is installing security software before initializing the database. We could employ an if-statement to do this, but by utilizing the ordered_steps function, we can also include additional Puppet code.

When you include this code:


oracle_database::before_database:		customer_team_1::security_software

in the hiera data for this team, the ordered_steps function will ensure the class customer_team_1::security_software is applied before the database class is applied. Since the ordered_steps function supports both before and after classes, we could also accomplish the same using this code:

oracle_database::after_oracle_software:		customer_team_1::security_software

What do you need to use this function?

We left out the parameters you need to add to the oracle_database class in order to make things clearer, but under the hood, ordered_steps executes a lot of parameter lookups. In order for us not to run into any Puppet warnings, those parameters have to be added to the class definition like this:

class oracle_database(
  Optional[String] $before_systl = undef,
  Optional[String] $before_os_users_and_groups = undef,
  Optional[String] $before_limits = undef,
  Optional[String] $before_packages = undef,
  Optional[String] $before_oracle_software = undef,
  Optional[String] $before_database = undef,
  Optional[String] $before_database_users = undef,
  Optional[String] $before_database_storage = undef,
  Optional[String] $systl = undef,
  Optional[String] $os_users_and_groups = undef,
  Optional[String] $limits = undef,
  Optional[String] $packages = undef,
  Optional[String] $oracle_software = undef,
  Optional[String] $database = undef,
  Optional[String] $database_users = undef,
  Optional[String] $database_storage = undef,
  Optional[String] $after_systl = undef,
  Optional[String] $after_os_users_and_groups = undef,
  Optional[String] $after_limits = undef,
  Optional[String] $after_packages = undef,
  Optional[String] $after_oracle_software = undef,
  Optional[String] $after_database = undef,
  Optional[String] $after_database_users = undef,
  Optional[String] $after_database_storage = undef,
) {
  easy_type::ordered_steps([
    'systl',
    'os_users_and_groups',
    'limits',
    'packages',
    'oracle_software',
    'database',
    'database_users',
    'database_storage']
  )
}

The easy_type::ordered_steps function is defined in the enterprisemodules-easy_type module. The enterprisemodules-easy_type module is a collection of functions, custom types, and other Puppet goodies that we use for all of our commercial modules. You are free to install and use it. Check the documentation on the Puppet forge for more information. To use this function, you’ll have to add this module to your Puppetfile

Summary

Do you want to make your team’s Puppet code easier to read and more concise, and better organized? While still allowing customizations to allow the code to fit every client team’s unique needs? Then using the easy_type::ordered_steps function is the way to go.

The easy_type::ordered_steps function not only allows you to make your Puppet code with the order steps pattern more concise, it also allows extensive customizations using hiera values. You can replace the current implementation with a team-specific implementation, or you can omit the step altogether. If you need to include code in the sequence, you can use the before or after option of the ordered_steps function.

If you could use a hand, we are here to help. Making good Puppet code is our bread and butter at Enterprise Modules. But besides developing our own modules, we are also helping customers build the best possible Puppet code. Do you think you could need some assistance? Don’t hesitate to contact us at info@enterprisemodules.com or by phone: +31 (0)653 847 326 for some consultancy.

About us

Enterprise Modules is the leading developer of enterprise-ready puppet modules for Oracle databases,Oracle WebLogic, and IBM MQ or DB2 software. Our puppet modules help sysadmins and DBAs to automate the installation, configuration, and management of their databases and application server systems. These modules allow them to make managed, consistent, repeatable, and fast changes to their infrastructure and automatically enforce the consistency.

For more information, please visit our website: www.enterprisemodules.com or contact us at info@enterprisemodules.com.