<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Enterprise-grade Puppet modules</title><description>On this site you can find information about supported enterprise-grade puppet modules. Puppet modules to install and manage Oracle databases, Oracle Weblogic and Fusion Middleware, IBM MQ, IBM Integration Bus and other enterprise-grade software.
</description><link>https://www.enterprisemodules.com/</link><atom:link href="https://www.enterprisemodules.com/feed.xml" rel="self" type="application/rss+xml"/><pubDate>Sun, 10 May 2026 13:52:18 +0200</pubDate><lastBuildDate>Sun, 10 May 2026 13:52:18 +0200</lastBuildDate><generator>Jekyll v3.8.3</generator><item><title>Why Now is the Time to Switch Your Oracle and WebLogic Puppet® Modules</title><description>&lt;p&gt;&lt;img src=&quot;/post-images/module-upgrade.webp&quot; alt=&quot;Why Now is the Time to Switch Your Oracle and WebLogic Puppet® Modules&quot; /&gt;
If you’re relying on the &lt;a href=&quot;https://forge.puppet.com/modules/biemond&quot;&gt;Biemond orawls and oradb puppet modules&lt;/a&gt; for managing Oracle and WebLogic in your Puppet® environment, there are some pressing issues you need to be aware of. These modules, once popular on Puppet® Forge, are on the brink of expiration. They haven’t been updated in over four years, and their GitHub repositories have been eerily quiet for just as long. Even worse, pull requests are gathering dust, unmerged, with no signs of life from the maintainers. But here’s the truth: Puppet® for Oracle and WebLogic is still very much alive and kicking.&lt;/p&gt;

&lt;h2 id=&quot;the-reality-of-the-situation&quot;&gt;The Reality of the Situation&lt;/h2&gt;

&lt;p&gt;Stale Modules: The &lt;a href=&quot;https://github.com/biemond/biemond-orawls&quot;&gt;biemond-orawls&lt;/a&gt; and &lt;a href=&quot;https://github.com/biemond/biemond-oradb&quot;&gt;biemond-oradb&lt;/a&gt; modules are outdated and on the verge of expiring. No updates, no new features, and a complete lack of support. Unmaintained Repositories: The GitHub repos are frozen in time. No activity, no responsiveness to pull requests. Essentially, you’re stuck with what you’ve got.&lt;/p&gt;

&lt;h2 id=&quot;but-all-is-not-lost&quot;&gt;But All is Not Lost&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;/&quot;&gt;Enterprise Modules&lt;/a&gt; is leading the way with their actively maintained &lt;a href=&quot;https://www.enterprisemodules.com/shop/&quot;&gt;Puppet modules for Oracle and WebLogic&lt;/a&gt;. Our modules don’t just keep up with the times—they’re at the cutting edge. Here’s why making the switch to &lt;a href=&quot;/&quot;&gt;Enterprise Modules&lt;/a&gt; is the smartest move you can make:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Full Support for the Latest Technology: Our modules are fully compatible with Puppet® 8 and the latest Oracle and WebLogic versions. You won’t be left behind using outdated software.&lt;/li&gt;
  &lt;li&gt;Continuous Updates and New Features: We’re not just maintaining these modules; we’re enhancing them. Expect regular updates that bring new features and keep your systems running smoothly.&lt;/li&gt;
  &lt;li&gt;Change doesn’t have to be hard—especially when you’ve got the right support. For a limited time, we’re offering special reduced rates and personalized assistance to help you transition from Biemond modules without a hitch.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;dont-get-left-behind---take-action-now&quot;&gt;Don’t Get Left Behind - Take Action Now&lt;/h2&gt;
&lt;p&gt;Managing Oracle and WebLogic with Puppet® is still the best choice for many enterprises. But you need tools that are reliable, up-to-date, and supported by a team that’s dedicated to your success. Don’t wait until your modules are expired and your systems are vulnerable. Contact us today to learn more about our special offer and discover how easy it is to transition to &lt;a href=&quot;/&quot;&gt;Enterprise Modules&lt;/a&gt;. Let us help you stay ahead of the curve. This exclusive offer won’t last forever, so act now to secure a seamless upgrade with zero stress and no disruption to your operations. Don’t miss out—make the switch today and enjoy the smoothest transition possible!&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://www.enterprisemodules.com/company/contact/&quot;&gt;Contact us&lt;/a&gt; now to take advantage of our special transition offer, including reduced rates and expert support to ensure a seamless migration. Don’t wait until it’s too late—reach out today and future-proof your Oracle and WebLogic management with &lt;a href=&quot;/&quot;&gt;Enterprise Modules&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;about-us&quot;&gt;About us&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;/&quot;&gt;Enterprise Modules&lt;/a&gt; is the leading developer of enterprise-ready &lt;a href=&quot;https://www.puppet.com&quot;&gt;puppet®&lt;/a&gt; modules for Oracle databases,Oracle WebLogic, and IBM MQ or DB2 software. Our &lt;a href=&quot;https://www.puppet.com&quot;&gt;puppet®&lt;/a&gt; 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.&lt;/p&gt;

&lt;p&gt;For more information, please visit our website: www.enterprisemodules.com or contact us at info@enterprisemodules.com.&lt;/p&gt;

</description><pubDate>Tue, 13 Aug 2024 00:00:00 +0200</pubDate><link>https://www.enterprisemodules.com/blog/2024/08/why-now-is-the-time-to-switch-your-oracle-and-weblogic-puppet-modules/</link><guid isPermaLink="true">https://www.enterprisemodules.com/blog/2024/08/why-now-is-the-time-to-switch-your-oracle-and-weblogic-puppet-modules/</guid><category>Puppet</category><category>WebLogic</category><category>Oracle</category><category>blog</category><category>puppet</category><category>oracle</category><category>weblogic</category></item><item><title>Book review: Puppet® 8 for DevOps engineers</title><description>&lt;p&gt;&lt;img src=&quot;/post-images/puppet-8-for-devops-engineers.png&quot; alt=&quot;Book review: Puppet® 8 for DevOps engineers&quot; /&gt;
At times, our clients inquire about recommended books on Puppet® that are both recent and informative. Unfortunately, we were unable to provide any suggestions for some time. However, with the release of David’s new Puppet® book &lt;a href=&quot;https://www.amazon.com/Puppet-DevOps-Engineers-infrastructure-enterprise/dp/180323170X&quot;&gt;“Puppet 8 for DevOps Engineers”&lt;/a&gt;, we are now able to recommend it with confidence to those seeking to enhance their Puppet® skills and streamline their automation processes.&lt;/p&gt;

&lt;h2 id=&quot;scope-of-the-book&quot;&gt;Scope of the book&lt;/h2&gt;

&lt;p&gt;Previously, most literature on Puppet® focused on the Puppet® language, which was extremely helpful at the time. However, Puppet® has since evolved to encompass much more. In addition to the language itself, one must also understand hiera data lookups, module creation and publication, and proper code structuring to ensure maintainability. Release management is also a crucial aspect of Puppet® use today. David’s book covers all of these topics in depth and with great clarity.&lt;/p&gt;

&lt;h2 id=&quot;shared-insights&quot;&gt;Shared Insights&lt;/h2&gt;

&lt;p&gt;David and we have both been working in the Puppet® domain for a while. It’s great to see that we share David’s view on how Puppet® users are evolving:&lt;/p&gt;

&lt;div class=&quot;quote-banner&quot;&gt;
&lt;span&gt;
  &lt;i class=&quot;fa fa-quote-left fa-2x&quot;&gt;&lt;/i&gt;
  &lt;h3&gt;Puppet has come a long way since its inception.&lt;/h3&gt;
&lt;/span&gt;

&lt;p&gt;Puppet has come a long way since its inception. It started off as a tool that relied heavily on developers to figure out how best to use it to solve problems. Today, it has evolved into a tool that offers standardized patterns and solutions that users can easily adopt for their automation and deployment needs. This shift has allowed users to focus on finding solutions rather than worrying about the underlying technology.&lt;/p&gt;

&lt;i class=&quot;fa fa-quote-right fa-2x&quot;&gt;&lt;/i&gt;
&lt;/div&gt;

&lt;h2 id=&quot;what-we-liked&quot;&gt;What we liked&lt;/h2&gt;

&lt;p&gt;We are highly regarded in the Puppet® community for our Oracle Puppet® modules. We appreciated that David used an example featuring Oracle in his explanation of roles and profiles.&lt;/p&gt;

&lt;div class=&quot;quote-banner&quot;&gt;
&lt;span&gt;
  &lt;i class=&quot;fa fa-quote-left fa-2x&quot;&gt;&lt;/i&gt;
  &lt;h3&gt;Roles versus profiles versus modules&lt;/h3&gt;
&lt;/span&gt;

&lt;p&gt;What can be confusing, at this point, is that you can end up with an Oracle &lt;strong&gt;Role&lt;/strong&gt;, an Oracle &lt;strong&gt;profile&lt;/strong&gt;, and an Oracle &lt;strong&gt;module&lt;/strong&gt;. So, while the Oracle module configures and installs Oracle with various parameters available to it to customize the installation, the Oracle profile is about how your organization uses this module and what other modules it might add to this technology stack. You might specify that you always use Oracle with a cluster service and, therefore, your Oracle profile contains both an Oracle module and a cluster module. Alternatively, it might pass parameters to the Oracle module within your profile, which set default kernel settings for your organization’s configuration.&lt;/p&gt;

&lt;i class=&quot;fa fa-quote-right fa-2x&quot;&gt;&lt;/i&gt;
&lt;/div&gt;

&lt;h2 id=&quot;summary&quot;&gt;Summary&lt;/h2&gt;

&lt;p&gt;If you are looking to learn or improve your skills in using Puppet® for automation and configuration management, then &lt;a href=&quot;https://www.amazon.com/Puppet-DevOps-Engineers-infrastructure-enterprise/dp/180323170X&quot;&gt;“Puppet 8 for DevOps Engineers”&lt;/a&gt; by David Sandilands is the perfect book for you. This book provides a comprehensive guide to Puppet® 8, including the Puppet® language, Hiera data lookups, versioning strategies, and best practices.&lt;/p&gt;

&lt;p&gt;What sets this book apart is the broad spectrum of subjects that David explains. The book is well-organized, with each chapter building upon the previous one, and includes hands-on exercises to reinforce learning. Overall, &lt;a href=&quot;https://www.amazon.com/Puppet-DevOps-Engineers-infrastructure-enterprise/dp/180323170X&quot;&gt;“Puppet 8 for DevOps Engineers”&lt;/a&gt; is a must-read for anyone looking to master Puppet® and take their automation skills to the next level. Although beginners at the start might be overwhelmed by the scope of the book, it is suitable for both beginners and experienced Puppet® users, and its practical approach makes it an invaluable resource for anyone working in DevOps.&lt;/p&gt;

&lt;p&gt;If even after reading this book (or before) you think you need assistance with your Puppet® setup, we are here to assist you.  We have been assisting customers getting the most out of their Puppet® setup for years. Don’t hesitate to contact us at &lt;a href=&quot;mailto:info@enterprisemodules.com&quot;&gt;info@enterprisemodules.com&lt;/a&gt; or by phone: +31 (0)653 847 326 for some consultancy.&lt;/p&gt;

&lt;h2 id=&quot;about-us&quot;&gt;About us&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;https://www.notion.so/&quot;&gt;Enterprise Modules&lt;/a&gt; is the leading developer of enterprise-ready &lt;a href=&quot;https://www.puppet.com/&quot;&gt;Puppet®&lt;/a&gt; modules for Oracle databases, Oracle WebLogic, and IBM MQ or DB2 software. Our Puppet® modules help sysadmins and DBAs 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 consistency.&lt;/p&gt;

&lt;p&gt;For more information, please visit our website: &lt;a href=&quot;http://www.enterprisemodules.com/&quot;&gt;www.enterprisemodules.com&lt;/a&gt; or contact us at &lt;a href=&quot;mailto:info@enterprisemodules.com&quot;&gt;info@enterprisemodules.com&lt;/a&gt;.&lt;/p&gt;
</description><pubDate>Wed, 12 Jul 2023 00:00:00 +0200</pubDate><link>https://www.enterprisemodules.com/blog/2023/07/book-review-puppet-8-for-devops-engineers/</link><guid isPermaLink="true">https://www.enterprisemodules.com/blog/2023/07/book-review-puppet-8-for-devops-engineers/</guid><category>puppet</category><category>blog</category><category>puppet</category></item><item><title>Customize the ordered steps Puppet® pattern with hiera values</title><description>&lt;p&gt;&lt;img src=&quot;/post-images/ordered-steps-customize.jpg&quot; alt=&quot;Customize the ordered steps Puppet® pattern with hiera values&quot; /&gt;
Do you want to make your team’s &lt;a href=&quot;https://www.puppet.com&quot;&gt;Puppet®&lt;/a&gt;  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 &lt;code class=&quot;highlighter-rouge&quot;&gt;easy_type::ordered_steps&lt;/code&gt; function is the way to go.&lt;/p&gt;

&lt;h2 id=&quot;introduction&quot;&gt;Introduction&lt;/h2&gt;

&lt;p&gt;The ordered steps &lt;a href=&quot;https://www.puppet.com&quot;&gt;Puppet®&lt;/a&gt;  pattern we introduced in our &lt;a href=&quot;blog/2022/08/how-to-use-the-ordered-steps-pattern-to-create-better-maintainable-puppet-code/&quot;&gt;last blog post&lt;/a&gt; helps you write more manageable &lt;a href=&quot;https://www.puppet.com&quot;&gt;Puppet®&lt;/a&gt;  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.&lt;/p&gt;

&lt;p&gt;This blog post introduces the &lt;code class=&quot;highlighter-rouge&quot;&gt;easy_type::orderd_steps&lt;/code&gt; function that allows for customizations to your flow by setting hiera values.&lt;/p&gt;

&lt;h2 id=&quot;what-is-the-problem&quot;&gt;What is the problem?&lt;/h2&gt;

&lt;p&gt;In our previous blog post, we used this example:&lt;/p&gt;

&lt;div class=&quot;language-puppet highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;oracle_database&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;contain&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;systl&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;contain&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;os_users_and_groups&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;contain&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;limits&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;contain&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;packages&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;contain&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;oracle_software&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;contain&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;database&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;contain&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;database_users&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;contain&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;database_storage&lt;/span&gt;

  &lt;span class=&quot;nc&quot;&gt;Class&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'systl'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Class&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'os_users_and_groups'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Class&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'limits'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Class&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'packages'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Class&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'oracle_software'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Class&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'database'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Class&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'database_users'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Class&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'database_storage'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Class&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'database '&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;What if your infrastructure team supports many client teams that all have their own ways of doing &lt;a href=&quot;https://www.puppet.com&quot;&gt;Puppet®&lt;/a&gt;  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.&lt;/p&gt;

&lt;p&gt;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!&lt;/p&gt;

&lt;h2 id=&quot;introducing-the-orderd_steps-function&quot;&gt;Introducing the orderd_steps function&lt;/h2&gt;

&lt;p&gt;The basic change consists of this code:&lt;/p&gt;

&lt;div class=&quot;language-puppet highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nf&quot;&gt;easy_type::ordered_steps&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;
  &lt;span class=&quot;s1&quot;&gt;'systl'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;s1&quot;&gt;'os_users_and_groups'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;s1&quot;&gt;'limits'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;s1&quot;&gt;'packages'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;s1&quot;&gt;'oracle_software'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;s1&quot;&gt;'database'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;s1&quot;&gt;'database_users'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;s1&quot;&gt;'database_storage'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The &lt;a href=&quot;https://www.puppet.com&quot;&gt;Puppet®&lt;/a&gt;  code above uses the &lt;code class=&quot;highlighter-rouge&quot;&gt;easy_type::ordered_steps&lt;/code&gt; 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.&lt;/p&gt;

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

&lt;h2 id=&quot;how-to-customize-the-behavior&quot;&gt;How to customize the behavior?&lt;/h2&gt;

&lt;p&gt;The &lt;code class=&quot;highlighter-rouge&quot;&gt;ordered_steps&lt;/code&gt; function is quite powerful under the hood. Let’s look at some scenarios to illustrate its power.&lt;/p&gt;

&lt;h3 id=&quot;skipping-a-step&quot;&gt;Skipping a step&lt;/h3&gt;

&lt;p&gt;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 &lt;code class=&quot;highlighter-rouge&quot;&gt;limits&lt;/code&gt; class from the manifest, or we could utilize an if-statement to fix this; however, the &lt;code class=&quot;highlighter-rouge&quot;&gt;ordered_steps&lt;/code&gt; 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:&lt;/p&gt;

&lt;div class=&quot;language-yaml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;s&quot;&gt;oracle_database::limits:&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;		&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;skip&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;the &lt;code class=&quot;highlighter-rouge&quot;&gt;ordered_steps&lt;/code&gt; function will skip adding the &lt;code class=&quot;highlighter-rouge&quot;&gt;limits&lt;/code&gt; class to your manifest. Thus implementing this use case.&lt;/p&gt;

&lt;h3 id=&quot;replacing-a-step&quot;&gt;Replacing a step&lt;/h3&gt;

&lt;p&gt;In the second use case, a team has unique requirements for creating OS users and groups. The current &lt;code class=&quot;highlighter-rouge&quot;&gt;os_users_and_groups&lt;/code&gt; class does not align with these preferences. Instead of adding this to the company-wide &lt;a href=&quot;https://www.puppet.com&quot;&gt;Puppet®&lt;/a&gt;  code, you would rather have the customer team manage it.&lt;/p&gt;

&lt;p&gt;When you include this code:&lt;/p&gt;

&lt;div class=&quot;language-yaml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;s&quot;&gt;oracle_database::os_users_and_groups&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;   &lt;span class=&quot;s&quot;&gt;customer_team_1::special_os_users_and_groups&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;in the hiera data for this team, instead of the standard class, the &lt;code class=&quot;highlighter-rouge&quot;&gt;ordered_steps&lt;/code&gt; function will call the class supplied by the customer team. As a result, this use case is implemented.&lt;/p&gt;

&lt;h3 id=&quot;executing-puppet-statements-before-or-after&quot;&gt;Executing Puppet® statements before or after&lt;/h3&gt;

&lt;p&gt;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 &lt;code class=&quot;highlighter-rouge&quot;&gt;ordered_steps&lt;/code&gt; function, we can also include additional Puppet® code.&lt;/p&gt;

&lt;p&gt;When you include this code:&lt;/p&gt;

&lt;div class=&quot;language-yaml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;
&lt;span class=&quot;s&quot;&gt;oracle_database::before_database:&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;		&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;customer_team_1::security_software&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;in the hiera data for this team, the &lt;code class=&quot;highlighter-rouge&quot;&gt;ordered_steps&lt;/code&gt; function will ensure the class &lt;code class=&quot;highlighter-rouge&quot;&gt;customer_team_1::security_software&lt;/code&gt; is applied before the &lt;code class=&quot;highlighter-rouge&quot;&gt;database&lt;/code&gt; class is applied. Since the &lt;code class=&quot;highlighter-rouge&quot;&gt;ordered_steps&lt;/code&gt; function supports both &lt;code class=&quot;highlighter-rouge&quot;&gt;before&lt;/code&gt; and &lt;code class=&quot;highlighter-rouge&quot;&gt;after&lt;/code&gt; classes, we could also accomplish the same using this code:&lt;/p&gt;

&lt;div class=&quot;language-yaml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;s&quot;&gt;oracle_database::after_oracle_software:&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;		&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;customer_team_1::security_software&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;what-do-you-need-to-use-this-function&quot;&gt;What do you need to use this function?&lt;/h2&gt;

&lt;p&gt;We left out the parameters you need to add to the &lt;code class=&quot;highlighter-rouge&quot;&gt;oracle_database&lt;/code&gt; class in order to make things clearer, but under the hood, &lt;code class=&quot;highlighter-rouge&quot;&gt;ordered_steps&lt;/code&gt; executes a lot of parameter lookups. In order for us not to run into any &lt;a href=&quot;https://www.puppet.com&quot;&gt;Puppet®&lt;/a&gt;  warnings, those parameters have to be added to the class definition like this:&lt;/p&gt;

&lt;div class=&quot;language-puppet highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;oracle_database&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
  &lt;span class=&quot;nc&quot;&gt;Optional&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$before_systl&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;undef&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;nc&quot;&gt;Optional&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$before_os_users_and_groups&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;undef&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;nc&quot;&gt;Optional&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$before_limits&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;undef&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;nc&quot;&gt;Optional&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$before_packages&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;undef&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;nc&quot;&gt;Optional&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$before_oracle_software&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;undef&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;nc&quot;&gt;Optional&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$before_database&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;undef&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;nc&quot;&gt;Optional&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$before_database_users&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;undef&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;nc&quot;&gt;Optional&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$before_database_storage&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;undef&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;nc&quot;&gt;Optional&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$systl&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;undef&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;nc&quot;&gt;Optional&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$os_users_and_groups&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;undef&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;nc&quot;&gt;Optional&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$limits&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;undef&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;nc&quot;&gt;Optional&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$packages&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;undef&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;nc&quot;&gt;Optional&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$oracle_software&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;undef&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;nc&quot;&gt;Optional&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$database&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;undef&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;nc&quot;&gt;Optional&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$database_users&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;undef&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;nc&quot;&gt;Optional&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$database_storage&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;undef&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;nc&quot;&gt;Optional&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$after_systl&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;undef&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;nc&quot;&gt;Optional&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$after_os_users_and_groups&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;undef&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;nc&quot;&gt;Optional&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$after_limits&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;undef&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;nc&quot;&gt;Optional&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$after_packages&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;undef&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;nc&quot;&gt;Optional&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$after_oracle_software&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;undef&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;nc&quot;&gt;Optional&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$after_database&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;undef&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;nc&quot;&gt;Optional&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$after_database_users&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;undef&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;nc&quot;&gt;Optional&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$after_database_storage&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;undef&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nf&quot;&gt;easy_type::ordered_steps&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;
    &lt;span class=&quot;s1&quot;&gt;'systl'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;s1&quot;&gt;'os_users_and_groups'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;s1&quot;&gt;'limits'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;s1&quot;&gt;'packages'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;s1&quot;&gt;'oracle_software'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;s1&quot;&gt;'database'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;s1&quot;&gt;'database_users'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;s1&quot;&gt;'database_storage'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The &lt;code class=&quot;highlighter-rouge&quot;&gt;easy_type::ordered_steps&lt;/code&gt; function is defined in the enterprisemodules-easy_type module. The enterprisemodules-easy_type module is a collection of functions, custom types, and other &lt;a href=&quot;https://www.puppet.com&quot;&gt;Puppet®&lt;/a&gt;  goodies that we use for all of our commercial modules. You are free to install and use it. Check the documentation on the &lt;a href=&quot;https://forge.puppet.com/modules/enterprisemodules/easy_type&quot;&gt;Puppet forge&lt;/a&gt; for more information. To use this function, you’ll have to add this module to your &lt;code class=&quot;highlighter-rouge&quot;&gt;Puppetfile&lt;/code&gt;&lt;/p&gt;

&lt;h2 id=&quot;summary&quot;&gt;Summary&lt;/h2&gt;

&lt;p&gt;Do you want to make your team’s &lt;a href=&quot;https://www.puppet.com&quot;&gt;Puppet®&lt;/a&gt;  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 &lt;code class=&quot;highlighter-rouge&quot;&gt;easy_type::ordered_steps&lt;/code&gt; function is the way to go.&lt;/p&gt;

&lt;p&gt;The &lt;code class=&quot;highlighter-rouge&quot;&gt;easy_type::ordered_steps&lt;/code&gt; function not only allows you to make your &lt;a href=&quot;https://www.puppet.com&quot;&gt;Puppet®&lt;/a&gt;  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 &lt;code class=&quot;highlighter-rouge&quot;&gt;ordered_steps&lt;/code&gt; function.&lt;/p&gt;

&lt;p&gt;If you could use a hand, we are here to help. Making good &lt;a href=&quot;https://www.puppet.com&quot;&gt;Puppet®&lt;/a&gt;  code is our bread and butter at Enterprise Modules. But besides developing our own modules, we are also helping customers build the best possible &lt;a href=&quot;https://www.puppet.com&quot;&gt;Puppet®&lt;/a&gt;  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.&lt;/p&gt;

&lt;h2 id=&quot;about-us&quot;&gt;About us&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;/&quot;&gt;Enterprise Modules&lt;/a&gt; is the leading developer of enterprise-ready &lt;a href=&quot;https://www.puppet.com&quot;&gt;puppet®&lt;/a&gt; modules for Oracle databases,Oracle WebLogic, and IBM MQ or DB2 software. Our &lt;a href=&quot;https://www.puppet.com&quot;&gt;puppet®&lt;/a&gt; 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.&lt;/p&gt;

&lt;p&gt;For more information, please visit our website: www.enterprisemodules.com or contact us at info@enterprisemodules.com.&lt;/p&gt;
</description><pubDate>Fri, 26 Aug 2022 00:00:00 +0200</pubDate><link>https://www.enterprisemodules.com/blog/2022/08/customize-the-ordered-steps-puppet-pattern,-with-hiera-values/</link><guid isPermaLink="true">https://www.enterprisemodules.com/blog/2022/08/customize-the-ordered-steps-puppet-pattern,-with-hiera-values/</guid><category>puppet</category><category>blog</category><category>puppet</category></item><item><title>How to use the ordered steps pattern to create better maintainable Puppet® code</title><description>&lt;p&gt;&lt;img src=&quot;/post-images/ordered_steps.jpg&quot; alt=&quot;How to use the ordered steps pattern to create better maintainable Puppet® code&quot; /&gt;
Managing the order of execution for your &lt;a href=&quot;https://www.puppet.com&quot;&gt;Puppet®&lt;/a&gt; classes is important to ensure that configuration is completed in the correct order. But there are so many ways how you can do this. What is a useful and maintainable way to do this? The ordered steps pattern allows you to manage the order of execution for classes. This article will discuss how to use the ordered steps pattern and provide some tips for creating maintainable &lt;a href=&quot;https://www.puppet.com&quot;&gt;Puppet®&lt;/a&gt; code.&lt;/p&gt;

&lt;h2 id=&quot;what-are-puppet-patterns-and-why-are-they-useful&quot;&gt;What are Puppet® patterns, and why are they useful?&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;https://www.puppet.com&quot;&gt;Puppet®&lt;/a&gt; patterns help you design and organize your &lt;a href=&quot;https://www.puppet.com&quot;&gt;Puppet®&lt;/a&gt; code. By using patterns, you can make your code more maintainable and easier to understand. The fact that a pattern has a name also facilitates discussion about it in your team and ensures familiarity to the team members when they see it. They know how it works. If you’d have to give a definition for a &lt;a href=&quot;https://www.puppet.com&quot;&gt;Puppet®&lt;/a&gt; pattern, this would be one (based on the &lt;a href=&quot;https://en.wikibooks.org/wiki/Introduction_to_Software_Engineering/Architecture/Design_Patterns&quot;&gt;definition of a software design pattern&lt;/a&gt;):&lt;/p&gt;

&lt;div class=&quot;quote-banner&quot;&gt;
&lt;span&gt;
  &lt;i class=&quot;fa fa-quote-left fa-2x&quot;&gt;&lt;/i&gt;
  &lt;h3&gt;Definition of a Puppet® Pattern&lt;/h3&gt;
&lt;/span&gt;

&lt;p&gt;A Puppet® pattern is a general, reusable solution to a commonly occurring problem in Puppet® code within a given context.&lt;/p&gt;

&lt;i class=&quot;fa fa-quote-right fa-2x&quot;&gt;&lt;/i&gt;
&lt;/div&gt;

&lt;p&gt;It is not a finished design that can be transformed directly into &lt;a href=&quot;https://www.puppet.com&quot;&gt;Puppet®&lt;/a&gt; code. Rather, it is a description or template for how to solve a problem that can be used in many different situations.&lt;/p&gt;

&lt;p&gt;There are several different &lt;a href=&quot;https://www.puppet.com&quot;&gt;Puppet®&lt;/a&gt; patterns, and each one is useful in different situations. One of the best-known &lt;a href=&quot;https://www.puppet.com&quot;&gt;Puppet®&lt;/a&gt; pattern is the &lt;a href=&quot;https://puppet.com/docs/pe/2019.8/osp/the_roles_and_profiles_method.html&quot;&gt;roles and profiles pattern&lt;/a&gt;.  This is a way of structuring your code so that you can easily reuse parts of it in different places. The roles and profiles pattern is especially useful for large &lt;a href=&quot;https://www.puppet.com&quot;&gt;Puppet®&lt;/a&gt; deployments, where you might have hundreds of different classes. The pattern allows you to make composable and reusable &lt;a href=&quot;https://www.puppet.com&quot;&gt;Puppet®&lt;/a&gt; building blocks. These building blocks are called &lt;a href=&quot;https://puppet.com/docs/pe/2019.8/osp/the_roles_and_profiles_method.html#rules_for_profile_classes&quot;&gt;profile classes&lt;/a&gt;. You can then pick multiple profile classes together and build &lt;a href=&quot;https://www.puppet.com&quot;&gt;Puppet®&lt;/a&gt; code that ensures a certain specific configuration. These classes are called &lt;a href=&quot;https://puppet.com/docs/pe/2019.8/osp/the_roles_and_profiles_method.html#rules_for_role_classes&quot;&gt;role classes&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;You can find more about the roles and profiles pattern &lt;a href=&quot;https://puppet.com/docs/pe/2019.8/osp/the_roles_and_profiles_method.html&quot;&gt;here&lt;/a&gt;and &lt;a href=&quot;https://ospassist.puppet.com/hc/en-us/articles/360043560913-The-roles-and-profiles-pattern-What-is-it-How-do-I-use-it-to-manage-my-infrastructure-and-configuration-more-easily-&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;what-is-the-ordered-steps-pattern-and-what-are-its-benefits&quot;&gt;What is the ordered steps pattern, and what are its benefits?&lt;/h2&gt;

&lt;p&gt;The ordered steps pattern is a &lt;a href=&quot;https://www.puppet.com&quot;&gt;Puppet®&lt;/a&gt; pattern that allows you to manage the order of execution of classes. This can be useful for classes that need to be executed in a specific order or when you want to ensure that a particular class is always executed before another task.&lt;/p&gt;

&lt;p&gt;There are several benefits to using the ordered steps pattern:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;It helps ensure that classes are executed in the correct order.&lt;/li&gt;
  &lt;li&gt;It can help improve the maintainability of your &lt;a href=&quot;https://www.puppet.com&quot;&gt;Puppet®&lt;/a&gt; code.&lt;/li&gt;
  &lt;li&gt;It can help reduce errors caused by incorrect ordering of classes.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This case really presents itself when writing roles and profile classes.&lt;/p&gt;

&lt;p&gt;Let’s look at an contrived example. You need to write &lt;a href=&quot;https://www.puppet.com&quot;&gt;Puppet®&lt;/a&gt; code to ensure the installation and maintenance of your Oracle database on your Linux systems. When you look at the Oracle documentation, you see that these steps need to be executed before the Oracle software can be installed:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Ensure correct sysctl settings are applied&lt;/li&gt;
  &lt;li&gt;Ensure correct OS users and groups are created.&lt;/li&gt;
  &lt;li&gt;Ensure correct limits are sets&lt;/li&gt;
  &lt;li&gt;Ensure correct required packages are installed.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;After the installation of the Oracle software, you want to ensure the database gets configured the correct way. You need to execute the next steps:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Create the database&lt;/li&gt;
  &lt;li&gt;Create the database users&lt;/li&gt;
  &lt;li&gt;Create the database storage setup (tablespaces)&lt;/li&gt;
  &lt;li&gt;etc.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2 id=&quot;our-first-attempt&quot;&gt;Our first attempt.&lt;/h2&gt;

&lt;p&gt;This is how your &lt;a href=&quot;https://www.puppet.com&quot;&gt;Puppet®&lt;/a&gt; code could look like:&lt;/p&gt;

&lt;div class=&quot;language-puppet highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;oracle_database&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;include&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;systl&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;include&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;os_users_and_groups&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;include&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;limits&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;include&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;packages&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;include&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;oracle_software&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;include&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;database&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;include&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;database_users&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;include&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;database_storage&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;As you can see, all of the steps are available in the &lt;a href=&quot;https://www.puppet.com&quot;&gt;Puppet®&lt;/a&gt; manifest and the code is pretty good readable. There are, however, some problems with this code. Although the order in which the code is written equals the requested order, &lt;a href=&quot;https://www.puppet.com&quot;&gt;Puppet®&lt;/a&gt; does not enforce this order. It might go correct (Puppet manifest order), But it might also execute the classed in another order. This can change depending on other &lt;a href=&quot;https://www.puppet.com&quot;&gt;Puppet®&lt;/a&gt; code included in your manifest.&lt;/p&gt;

&lt;h2 id=&quot;second-attempt&quot;&gt;Second attempt&lt;/h2&gt;

&lt;p&gt;Let’s fix that. To fix this, we include explicit ordering.&lt;/p&gt;

&lt;div class=&quot;language-puppet highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;oracle_database&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;include&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;systl&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;include&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;os_users_and_groups&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;include&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;limits&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;include&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;packages&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;include&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;oracle_software&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;include&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;database&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;include&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;database_users&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;include&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;database_storage&lt;/span&gt;

  &lt;span class=&quot;nc&quot;&gt;Class&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'systl'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Class&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'os_users_and_groups'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Class&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'limits'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Class&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'packages'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Class&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'oracle_software'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Class&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'database'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Class&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'database_users'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Class&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'database_storage'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;As you can see, we have used the &lt;code class=&quot;highlighter-rouge&quot;&gt;-&amp;gt;&lt;/code&gt; syntax to describe explicit ordering between the classes. Now everything should be ok….? Yes, it might. But you might also run into ordering issues when your classes include other classes. When using &lt;code class=&quot;highlighter-rouge&quot;&gt;include&lt;/code&gt;, &lt;a href=&quot;https://www.puppet.com&quot;&gt;Puppet®&lt;/a&gt; enforces the ordering on the specified classes but not on any included classes. This might lead to &lt;a href=&quot;https://www.puppet.com&quot;&gt;Puppet®&lt;/a&gt; code that executes some code included in the &lt;code class=&quot;highlighter-rouge&quot;&gt;sysctl&lt;/code&gt; class very late in the execution, resulting in an error.&lt;/p&gt;

&lt;h2 id=&quot;final-version&quot;&gt;Final version&lt;/h2&gt;

&lt;p&gt;A fix for that is easy. Change all the &lt;code class=&quot;highlighter-rouge&quot;&gt;include&lt;/code&gt; for &lt;code class=&quot;highlighter-rouge&quot;&gt;contain&lt;/code&gt;.&lt;/p&gt;

&lt;div class=&quot;language-puppet highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;oracle_database&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;contain&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;systl&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;contain&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;os_users_and_groups&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;contain&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;limits&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;contain&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;packages&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;contain&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;oracle_software&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;contain&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;database&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;contain&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;database_users&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;contain&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;database_storage&lt;/span&gt;

  &lt;span class=&quot;nc&quot;&gt;Class&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'systl'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Class&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'os_users_and_groups'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Class&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'limits'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Class&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'packages'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Class&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'oracle_software'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Class&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'database'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Class&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'database_users'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Class&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'database_storage'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Class&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'database '&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;See &lt;a href=&quot;https://puppet.com/docs/puppet/7/lang_containment.html&quot;&gt;here&lt;/a&gt; for a full description on &lt;a href=&quot;https://www.puppet.com&quot;&gt;Puppet®&lt;/a&gt; containment. There is also a good video explaining this &lt;a href=&quot;https://www.youtube.com/watch?v=jvDLXykcxiA&quot;&gt;here&lt;/a&gt;. Now the explicit ordering of all requirements is ensured.&lt;/p&gt;

&lt;h2 id=&quot;could-this-be-done-differently&quot;&gt;Could this be done differently?&lt;/h2&gt;

&lt;p&gt;A disadvantage of this solution is that ordering is done at a fairly high level. If an error is raised in the &lt;code class=&quot;highlighter-rouge&quot;&gt;sysctl&lt;/code&gt; class, all other &lt;a href=&quot;https://www.puppet.com&quot;&gt;Puppet®&lt;/a&gt; code in this class is skipped. You probably could safely apply some parts of some other classes.&lt;/p&gt;

&lt;p&gt;However, doing this would mean applying ordering on a much lower level, for example, on the individual resource level. It is our experience that this leads to:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;More coupling between the classes, thus lesser reusability&lt;/li&gt;
  &lt;li&gt;greater chance of circular dependencies&lt;/li&gt;
  &lt;li&gt;More difficult to understand&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These reasons are enough for us not to do this.&lt;/p&gt;

&lt;h2 id=&quot;how-to-use-the-ordered-steps-pattern-in-puppet-code&quot;&gt;How to use the ordered steps pattern in &lt;a href=&quot;https://www.puppet.com&quot;&gt;Puppet®&lt;/a&gt; code&lt;/h2&gt;

&lt;p&gt;As explained before, you can use this pattern to ensure ordering between some (high-level) classes. Let’s see how we can use the pattern to create a role class.&lt;/p&gt;

&lt;div class=&quot;language-puppet highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;role&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;contain&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;base_profile&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;contain&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;database_profile&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;contain&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;application_server_profile&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;contain&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;application_profile&lt;/span&gt;

  &lt;span class=&quot;nc&quot;&gt;Class&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'base_profile'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Class&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'database_profile'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Class&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'application_server_profile'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Class&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'application_profile'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This class manages a server with an application that needs both a database and an application server. A best practice is to extract the configuration required for all servers- regardless of their role -to what we call &lt;code class=&quot;highlighter-rouge&quot;&gt;base_profile&lt;/code&gt;. So, &lt;code class=&quot;highlighter-rouge&quot;&gt;base_profile&lt;/code&gt; contains elements like:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;DNS configuration&lt;/li&gt;
  &lt;li&gt;Network configuration&lt;/li&gt;
  &lt;li&gt;Generic yum repositories&lt;/li&gt;
  &lt;li&gt;NTP configuration&lt;/li&gt;
  &lt;li&gt;timezone configuration&lt;/li&gt;
  &lt;li&gt;Common OS users and groups&lt;/li&gt;
  &lt;li&gt;etc.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We want to ensure our network configuration and DNS setup are correct before continuing. By ensuring the &lt;code class=&quot;highlighter-rouge&quot;&gt;base_profile&lt;/code&gt; class finishes successfully, we can then move on and apply the classes &lt;code class=&quot;highlighter-rouge&quot;&gt;database_profile&lt;/code&gt;, &lt;code class=&quot;highlighter-rouge&quot;&gt;application_server_profile&lt;/code&gt; followed by &lt;code class=&quot;highlighter-rouge&quot;&gt;application_profile&lt;/code&gt;. Doing things in this specific order guarantees a running application that all underlying components are working perfectly.&lt;/p&gt;

&lt;h2 id=&quot;examples-of-how-to-use-the-ordered-steps-pattern-in-practice&quot;&gt;Examples of how to use the ordered steps pattern in practice&lt;/h2&gt;

&lt;p&gt;Most people use ordered steps in role and profile classes, but you can also find them in some component modules on the &lt;a href=&quot;https://forge.puppet.com&quot;&gt;Puppet Forge&lt;/a&gt;. For example:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/voxpupuli/puppet-prometheus/blob/master/manifests/server.pp#L92-L100&quot;&gt;puppet-prometheus&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/voxpupuli/puppet-gitlab/blob/master/manifests/init.pp#L200-L208&quot;&gt;puppet-gitlab&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/puppetlabs/puppetlabs-kubernetes/blob/main/manifests/init.pp#L761-L773&quot;&gt;puppetlabs-kubernetes&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you look around, you can probably find many more.&lt;/p&gt;

&lt;h2 id=&quot;summary&quot;&gt;Summary&lt;/h2&gt;

&lt;p&gt;Puppet patterns are useful because they allow you to modularize your code, making it more maintainable. The ordered steps pattern is one of the used &lt;a href=&quot;https://www.puppet.com&quot;&gt;Puppet®&lt;/a&gt; patterns and allows you to ensure that certain classes are always executed in a specific order. You can use this pattern when creating role or profile classes, or when creating a component class.&lt;/p&gt;

&lt;p&gt;When used correctly, the ordered steps pattern can help you create more maintainable and understandable &lt;a href=&quot;https://www.puppet.com&quot;&gt;Puppet®&lt;/a&gt; code. However, it is important to note that this pattern should only be used when necessary. Overusing this pattern can lead to more coupling between classes and So, use this pattern sparingly and only when it makes sense for your code.&lt;/p&gt;

&lt;p&gt;We frequently utilize this &lt;a href=&quot;https://www.puppet.com&quot;&gt;Puppet®&lt;/a&gt; pattern in our code for Oracle databases, WebLogic, IBM DB2 and IBM MQ software. So, we created some handy functions to make it simpler to write code with ordered steps. We cover that more in-depth in our &lt;a href=&quot;/blog/2022/08/customize-the-ordered-steps-puppet-pattern,-with-hiera-values/&quot;&gt;next blog post&lt;/a&gt;.&lt;/p&gt;

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

&lt;h2 id=&quot;about-us&quot;&gt;About us&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;/&quot;&gt;Enterprise Modules&lt;/a&gt; is the leading developer of enterprise-ready &lt;a href=&quot;https://www.puppet.com&quot;&gt;puppet®&lt;/a&gt; modules for Oracle databases,Oracle WebLogic, and IBM MQ or DB2 software. Our &lt;a href=&quot;https://www.puppet.com&quot;&gt;puppet®&lt;/a&gt; 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.&lt;/p&gt;

&lt;p&gt;For more information, please visit our website: www.enterprisemodules.com or contact us at info@enterprisemodules.com.&lt;/p&gt;
</description><pubDate>Fri, 19 Aug 2022 00:00:00 +0200</pubDate><link>https://www.enterprisemodules.com/blog/2022/08/how-to-use-the-ordered-steps-pattern-to-create-better-maintainable-puppet-code/</link><guid isPermaLink="true">https://www.enterprisemodules.com/blog/2022/08/how-to-use-the-ordered-steps-pattern-to-create-better-maintainable-puppet-code/</guid><category>puppet</category><category>blog</category><category>puppet</category></item><item><title>Cleanup temporary files in Puppet</title><description>&lt;p&gt;&lt;img src=&quot;/post-images/cleanup.jpg&quot; alt=&quot;Cleanup temporary files in Puppet®&quot; /&gt;
In a Puppet® manifest, you sometimes need to make a temporary file. For example, a configuration file to be passed to an installer. Naturally, you want to clean up behind you. But in the end, something as simple as this turns out to be rather complicated. Unnecessary complicated. So that’s why we made a solution for that.&lt;/p&gt;

&lt;h2 id=&quot;why-not-ensure--absent&quot;&gt;Why not ensure =&amp;gt; absent?&lt;/h2&gt;

&lt;p&gt;Puppet allows you to manage a resource only once. This is to ensure consistent manifests and configuration results. Usually, that is excellent. But it hurts us for this use case. Because you can only add a &lt;code class=&quot;highlighter-rouge&quot;&gt;file&lt;/code&gt; once to a manifest, you cannot use the &lt;a href=&quot;https://puppet.com/docs/puppet/7/types/file.html&quot;&gt;Puppet &lt;code class=&quot;highlighter-rouge&quot;&gt;file&lt;/code&gt; resource&lt;/a&gt; to both create and remove the file in the same manifest.&lt;/p&gt;

&lt;h2 id=&quot;lets-use-tidy&quot;&gt;Let’s use &lt;code class=&quot;highlighter-rouge&quot;&gt;tidy&lt;/code&gt;&lt;/h2&gt;

&lt;p&gt;At first glance, the &lt;a href=&quot;https://puppet.com/docs/puppet/7/types/tidy.html&quot;&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;tidy&lt;/code&gt; resource&lt;/a&gt; looks like the solution. But under the hood, &lt;code class=&quot;highlighter-rouge&quot;&gt;tidy&lt;/code&gt; resource add’s &lt;code class=&quot;highlighter-rouge&quot;&gt;file&lt;/code&gt; resources. To the existing manifest (generate). If your manifest already contains a file =&amp;gt; ensure, The &lt;code class=&quot;highlighter-rouge&quot;&gt;tidy&lt;/code&gt; generator will not (it can’t) create a file =&amp;gt; absent resource to the same manifest. The annoying thing is that it doesn’t tell you about it.&lt;/p&gt;

&lt;h2 id=&quot;a-simple-exec-will-do-the-job&quot;&gt;A simple exec will do the job.&lt;/h2&gt;

&lt;p&gt;A simple way around these shortcomings is to use the &lt;a href=&quot;https://puppet.com/docs/puppet/7/types/exec.html&quot;&gt;exec resource&lt;/a&gt; and issue the &lt;code class=&quot;highlighter-rouge&quot;&gt;/bin/rm -f&lt;/code&gt; command. One of the downsides of doing this is that it is OS-dependent. If you want your manifest to work on multiple OS-es, you might have to write a lot of code to remove the correct file.&lt;/p&gt;

&lt;p&gt;Another downside of using an &lt;code class=&quot;highlighter-rouge&quot;&gt;exec&lt;/code&gt; resource might be ordering. You will have to ensure that the file is removed only after it is used. If it is used multiple times in the manifest and in different if blocks, your ordering can become a bit complicated. At least too difficult for something simple as removing your trash.&lt;/p&gt;

&lt;h2 id=&quot;the-cleanup-resource&quot;&gt;The cleanup resource&lt;/h2&gt;

&lt;p&gt;The &lt;a href=&quot;https://forge.puppet.com/modules/enterprisemodules/easy_type&quot;&gt;easy_type module&lt;/a&gt; contains a solution for the dilemma. The &lt;a href=&quot;https://www.enterprisemodules.com/docs/easy_type/cleanup.html&quot;&gt;cleanup&lt;/a&gt; resource. As the name implies, it cleans up. Let’s see how we can use this.&lt;/p&gt;

&lt;div class=&quot;language-puppet highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;file&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'/data/my_temporary_file'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;py&quot;&gt;ensure&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'present'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;py&quot;&gt;content&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'my_data = true'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;cleanup&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'/data/my_temporary_file'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This example shows the basic usage of the &lt;code class=&quot;highlighter-rouge&quot;&gt;cleanup&lt;/code&gt; resource in combination with creating a temporary file. At the end of the Puppet® run, the &lt;code class=&quot;highlighter-rouge&quot;&gt;cleanup&lt;/code&gt; resource will ensure that the file  &lt;code class=&quot;highlighter-rouge&quot;&gt;/data/my_temporary_file&lt;/code&gt; is removed. Because the &lt;code class=&quot;highlighter-rouge&quot;&gt;cleanup&lt;/code&gt; resource is in no way connected to the Puppet® &lt;code class=&quot;highlighter-rouge&quot;&gt;file&lt;/code&gt; resource, you can use them both together without a chance of duplicate resources.&lt;/p&gt;

&lt;h2 id=&quot;no-ordering&quot;&gt;No ordering?&lt;/h2&gt;

&lt;p&gt;Yes no ordering! That was not a typo. The &lt;code class=&quot;highlighter-rouge&quot;&gt;cleanup&lt;/code&gt; resource removes the files after &lt;strong&gt;all&lt;/strong&gt; of the Puppet® code has been applied. To show you how this works, let’s use this contrived example:&lt;/p&gt;

&lt;div class=&quot;language-puppet highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;cleanup&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'/a.a'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;py&quot;&gt;loglevel&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'notice'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;When we run this manifest you get this output:&lt;/p&gt;
&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Notice: Compiled catalog for oradb.example.com in environment production in 0.01 seconds
Notice: Applied catalog in 0.01 seconds
Notice: /Stage[main]/Main/Cleanup[/a.a]: Cleaning files marked for cleanup.
Notice: /Stage[main]/Main/Cleanup[/a.a]: File /a.a not found, skipping cleanup...
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Two things are worth noticing. The first thing is:: the cleanup starts &lt;strong&gt;after&lt;/strong&gt; the whole manifest is applied (e.g. the message &lt;code class=&quot;highlighter-rouge&quot;&gt;Notice: Applied catalog in 0.01 seconds&lt;/code&gt;). There is &lt;strong&gt;no&lt;/strong&gt; message during the application of the manifest. The second thing is that it will &lt;strong&gt;not&lt;/strong&gt; fail when the file is not available. This means that you can be flexible with when and how often you a &lt;code class=&quot;highlighter-rouge&quot;&gt;cleanup&lt;/code&gt; resource.&lt;/p&gt;

&lt;h2 id=&quot;multiple-file-cleanup&quot;&gt;Multiple file cleanup&lt;/h2&gt;

&lt;p&gt;Like all Puppet® resources, you can use an array of strings as a title. See this example:&lt;/p&gt;

&lt;div class=&quot;language-puppet highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$files_to_cleanup&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
  &lt;span class=&quot;s1&quot;&gt;'/tmp/my_config_file'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;s1&quot;&gt;'/tmp/my_tmp_dir'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;s1&quot;&gt;'/tmp/my_second_tmp/*.txt'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;cleanup&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$files_to_cleanup&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Here you can see the usage of an array as a title and the use of different file specs to be used for cleanup of files.&lt;/p&gt;

&lt;h2 id=&quot;meaningful-title&quot;&gt;Meaningful title&lt;/h2&gt;

&lt;p&gt;Although the &lt;code class=&quot;highlighter-rouge&quot;&gt;cleanup&lt;/code&gt; resource doesn’t give any messages during normal operation (e.g., default loglevel is &lt;code class=&quot;highlighter-rouge&quot;&gt;debug&lt;/code&gt;), it might still be useful to use a more meaningful text as a title. You can!&lt;/p&gt;

&lt;div class=&quot;language-puppet highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$files_to_cleanup&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
  &lt;span class=&quot;s1&quot;&gt;'/tmp/my_config_file'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;s1&quot;&gt;'/tmp/my_tmp_dir'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;s1&quot;&gt;'/tmp/my_second_tmp/*.txt'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;cleanup&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'All the temporary stuff'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;py&quot;&gt;file_name&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$files_to_cleanup&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;py&quot;&gt;loglevel&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'notice'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Here is the output of this code:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Notice: Compiled catalog for oradb.example.com in environment production in 0.01 seconds
Notice: Applied catalog in 0.01 seconds
Notice: /Stage[main]/Main/Cleanup[All the temporary stuff]: Cleaning files marked for cleanup.
Notice: /Stage[main]/Main/Cleanup[All the temporary stuff]: File /tmp/my_config_file not found, skipping cleanup...
Notice: /Stage[main]/Main/Cleanup[All the temporary stuff]: File /tmp/my_tmp_dir not found, skipping cleanup...
Notice: /Stage[main]/Main/Cleanup[All the temporary stuff]: File /tmp/my_second_tmp/*.txt not found, skipping cleanup...
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;As you can see, the title now contains a meaningful text.&lt;/p&gt;

&lt;h2 id=&quot;where-is-the-cleanup-resource-defined&quot;&gt;Where is the &lt;code class=&quot;highlighter-rouge&quot;&gt;cleanup&lt;/code&gt; resource defined?&lt;/h2&gt;

&lt;p&gt;The &lt;code class=&quot;highlighter-rouge&quot;&gt;cleanup&lt;/code&gt; custom types are defined in the &lt;a href=&quot;https://forge.puppet.com/modules/enterprisemodules/easy_type&quot;&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;enterprisemodules-easy_type&lt;/code&gt; module&lt;/a&gt;. The  &lt;a href=&quot;https://forge.puppet.com/modules/enterprisemodules/easy_type&quot;&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;enterprisemodules-easy_type&lt;/code&gt; module&lt;/a&gt; is a collection of functions, custom types, and other Puppet® goodies we use for all of our commercial modules. You are free to install and use it. Check the documentation on the &lt;a href=&quot;https://forge.puppet.com/modules/enterprisemodules/easy_type&quot;&gt;Puppet forge&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;Something simple as cleaning up behind you was unnecessarily tricky before. But with the introduction of the &lt;a href=&quot;https://www.enterprisemodules.com/docs/easy_type/cleanup.html&quot;&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;cleanup&lt;/code&gt; resource&lt;/a&gt; it has become as easy as it should be.&lt;/p&gt;

&lt;p&gt;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 &lt;a href=&quot;https://www.enterprisemodules.com/company/contact/&quot;&gt;contact us&lt;/a&gt; at &lt;a href=&quot;mailto:info@enterprisemodules.com&quot;&gt;info@enterprisemodules.com&lt;/a&gt; or by phone: +31 (0)653 847 326 for some consultancy.&lt;/p&gt;

&lt;h2 id=&quot;about-us&quot;&gt;About us&lt;/h2&gt;

&lt;p&gt;Enterprise modules is the leading developer of enterprise-ready Puppet® modules for Oracle databases,Oracle WebLogic, and IBM MQ 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.&lt;/p&gt;
</description><pubDate>Mon, 14 Feb 2022 00:00:00 +0100</pubDate><link>https://www.enterprisemodules.com/blog/2022/02/cleanup-temporary-files-in-puppet/</link><guid isPermaLink="true">https://www.enterprisemodules.com/blog/2022/02/cleanup-temporary-files-in-puppet/</guid><category>puppet</category><category>blog</category><category>puppet</category></item><item><title>Automate Puppet® fact caching management</title><description>&lt;p&gt;&lt;img src=&quot;/post-images/fact-caching.jpg&quot; alt=&quot;Automate Puppet® fact caching management&quot; /&gt;
Gathering facts about your system is an essential part of a Puppet® run. Most facts can be fetched very quickly and don’t significantly impact the speed of your Puppet® run. However, some facts can take a considerable time to resolve and have a big impact on the time it takes Puppet® to run. Since facter version 4, you can cache facts. Facts that take up a lot of time and/or are not very volatile can be cached. Caching of facts is controlled by a configuration file on your system. In this blog post, we show you how you can manage the contents of this configuration file with Puppet.&lt;/p&gt;

&lt;h2 id=&quot;how-it-works&quot;&gt;How it works&lt;/h2&gt;
&lt;p&gt;The &lt;code class=&quot;highlighter-rouge&quot;&gt;facter.conf&lt;/code&gt; file is a configuration file that allows you to cache and block fact groups and facts, and manage how Facter interacts with your system. It contains segments about grouping facts, settings for caching facts, and global settings for facts. &lt;a href=&quot;https://puppet.com/docs/puppet/7/configuring_facter.html&quot;&gt;Here is the full Puppet® documentation.&lt;/a&gt; for the content of this file.&lt;/p&gt;

&lt;h2 id=&quot;a-use-case&quot;&gt;A use case.&lt;/h2&gt;

&lt;p&gt;Let’s say we have a fact that contains the installed patch information about your installed Oracle version. Unfortunately, it takes quite some time to gather this information. Also, this information doesn’t change very often. ( Not every Puppet® run or every day). This combination of properties makes this fact an ideal candidate for fact caching.&lt;/p&gt;

&lt;h2 id=&quot;enable-fact-caching&quot;&gt;Enable fact caching&lt;/h2&gt;

&lt;p&gt;To enable fact caching for the fact `ora_installed_patches’ from within Puppet, you can add this code to your Puppet® codebase:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Puppet&quot;&gt;fact_config { 'ora_installed_patches':
  ttl =&amp;gt;  '24 hours'
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This segment of Puppet® code will tell Puppet® to add the following line to your &lt;code class=&quot;highlighter-rouge&quot;&gt;facter.conf&lt;/code&gt; file.&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;facts : {
  ttls : [
     { &quot;ora_installed_patches&quot; : 24 hours },
  ]
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Effectively telling facter to cache the fact &lt;code class=&quot;highlighter-rouge&quot;&gt;ora_installed_patches&lt;/code&gt; for 24 hours. See &lt;a href=&quot;https://www.enterprisemodules.com/docs/easy_type/fact_config.html&quot;&gt;the documentation&lt;/a&gt; for this type. for more details.&lt;/p&gt;

&lt;h2 id=&quot;invalidating-cache&quot;&gt;Invalidating cache&lt;/h2&gt;

&lt;p&gt;So caching this information is excellent. It speeds up your Puppet® run. But If we use Puppet® to install or remove a patch, we want to tell facter to invalidate the cache. How do we do that? For caching invalidation,  &lt;a href=&quot;https://forge.puppet.com/modules/enterprisemodules/easy_type&quot;&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;easy_type&lt;/code&gt;&lt;/a&gt; has the type &lt;a href=&quot;https://www.enterprisemodules.com/docs/easy_type/fact_cache.html&quot;&gt;fact_cache&lt;/a&gt;. Here is some code invalidating the &lt;code class=&quot;highlighter-rouge&quot;&gt;ora_installed_patches&lt;/code&gt; cache after some patches are installed:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;fact_cache {'ora_installed_patches':
  ensure =&amp;gt; absent,
  refreshonly =&amp;gt; true,
}
Ora_patch&amp;lt;||&amp;gt; ~&amp;gt; Fact_cache['ora_installed_patches']
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Let’s look at that in more detail. The &lt;code class=&quot;highlighter-rouge&quot;&gt;fact_cache {'ora_installed_patches': ensure =&amp;gt; absent}&lt;/code&gt; part, tells Puppet® to absent(=remove) the facter cache for fact &lt;code class=&quot;highlighter-rouge&quot;&gt;ora_installed_patches&lt;/code&gt;. The &lt;code class=&quot;highlighter-rouge&quot;&gt;refreshonly =&amp;gt; true&lt;/code&gt; part tells Puppet® &lt;strong&gt;only&lt;/strong&gt; to do this when it is notified.&lt;/p&gt;

&lt;p&gt;The line &lt;code class=&quot;highlighter-rouge&quot;&gt;Ora_patch&amp;lt;||&amp;gt; ~&amp;gt; Fact_cache['ora_installed_patches']&lt;/code&gt; ensures that every time a &lt;code class=&quot;highlighter-rouge&quot;&gt;Ora_patch&lt;/code&gt; is added or removed, the fact_cache &lt;code class=&quot;highlighter-rouge&quot;&gt;ora_installed_patches&lt;/code&gt; is notified. Thus completing the sequence of events needed to invalidate the cache.&lt;/p&gt;

&lt;h2 id=&quot;where-are-these-facter-types-defined&quot;&gt;Where are these facter types defined?&lt;/h2&gt;

&lt;p&gt;These Puppet® custom types are defined in the &lt;a href=&quot;https://forge.puppet.com/modules/enterprisemodules/easy_type&quot;&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;enterprisemodules-easy_type&lt;/code&gt; module&lt;/a&gt;. The  &lt;a href=&quot;https://forge.puppet.com/modules/enterprisemodules/easy_type&quot;&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;enterprisemodules-easy_type&lt;/code&gt; module&lt;/a&gt; is a collection of functions, custom types, and other Puppet® goodies we use for all of our commercial modules. You are free to install and use it. Check the documentation on the &lt;a href=&quot;https://forge.puppet.com/modules/enterprisemodules/easy_type&quot;&gt;Puppet forge&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;When a fact takes a long time and doesn’t change very often, it is an ideal candidate for fact caching. With our types to manage fact caching, you can easily control this from within Puppet. 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 &lt;a href=&quot;https://www.enterprisemodules.com/company/contact/&quot;&gt;contact us&lt;/a&gt; at &lt;a href=&quot;mailto:info@enterprisemodules.com&quot;&gt;info@enterprisemodules.com&lt;/a&gt; or by phone: +31 (0)653 847 326 for some consultancy.&lt;/p&gt;

&lt;h2 id=&quot;about-us&quot;&gt;About us&lt;/h2&gt;

&lt;p&gt;Enterprise modules is the leading developer of enterprise-ready Puppet® modules for Oracle databases,Oracle WebLogic, and IBM MQ 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.&lt;/p&gt;
</description><pubDate>Wed, 09 Feb 2022 00:00:00 +0100</pubDate><link>https://www.enterprisemodules.com/blog/2022/02/automate-puppet-fact-caching-management/</link><guid isPermaLink="true">https://www.enterprisemodules.com/blog/2022/02/automate-puppet-fact-caching-management/</guid><category>puppet</category><category>blog</category><category>puppet</category></item><item><title>Vulnerability management with Puppet</title><description>&lt;p&gt;&lt;img src=&quot;/post-images/vulnerability.jpg&quot; alt=&quot;Vulnerability management with Puppet®&quot; /&gt;
The vulnerability in log4j has once again shown us that detecting and resolving vulnerabilities in your IT infrastructure can be a daunting and very time-consuming task. Now some tools are available to &lt;a href=&quot;https://puppet.com/blog/find-and-mitigate-log4j-vulnerabilities-with-puppet-enterprise/&quot;&gt;detect the log4j vulnerability&lt;/a&gt;. That is good, but only targeted at the log4j vulnerability. How about other vulnerabilities? You can be sure other vulnerabilities are coming. Hopefully not soon, but they will come! How can you be prepared? The best way to ensure that you can easily detect and fix these issues is to integrate them into your current way of working and your current set of tools. The &lt;a href=&quot;https://forge.puppet.com/modules/enterprisemodules/vulnerability&quot;&gt;Puppet module vulnerability&lt;/a&gt; does just that. This blog post will show you how you can install and use it.&lt;/p&gt;

&lt;h2 id=&quot;introducing-the-vulnerability-module&quot;&gt;Introducing the vulnerability module.&lt;/h2&gt;

&lt;p&gt;The &lt;a href=&quot;https://forge.puppet.com/modules/enterprisemodules/vulnerability&quot;&gt;vulnerabnility module&lt;/a&gt; from &lt;a href=&quot;https://www.enterprisemodules.com/&quot;&gt;Enterprise Modules&lt;/a&gt;, seamlessly integrates vulnerability scanning into your Puppet® workflow. It works both with Puppet® Open Source and Puppet Enterprise®. The information about all of the found vulnerabilities (CVE’s) on your system(s) are available as a fact. This means that you can not only use Puppet® to detect the vulnerabilities but also use Puppet’s extensive configuration management features to mitigate any of the found vulnerabilities.&lt;/p&gt;

&lt;h2 id=&quot;lets-install-the-vulnerability-module&quot;&gt;Let’s install the vulnerability module.&lt;/h2&gt;

&lt;p&gt;Since it is a regular Puppet® module, installing it is as easy as adding just another module to your Puppet® codebase. Add this line to your &lt;code class=&quot;highlighter-rouge&quot;&gt;Puppetfile&lt;/code&gt;&lt;/p&gt;

&lt;div class=&quot;language-ruby highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;mod&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'enterprisemodules-vulnerability'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Or when you are using a manual installation process, use this command:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;puppet module &lt;span class=&quot;nb&quot;&gt;install &lt;/span&gt;enterprisemodules-vulnerability
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;For Linux systems, installing just the &lt;code class=&quot;highlighter-rouge&quot;&gt;enterprisemodules-vulnerability&lt;/code&gt; module is enough. For Windows systems, there are some dependencies that you’ll have to add to the &lt;code class=&quot;highlighter-rouge&quot;&gt;Puppetfile&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;language-ruby highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;mod&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'puppetlabs-powershell'&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;mod&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'puppet-archive'&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;mod&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'puppetlabs-pwshlib'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;activate&quot;&gt;Activate&lt;/h2&gt;

&lt;p&gt;Besides installing the &lt;a href=&quot;https://forge.puppet.com/modules/enterprisemodules/vulnerability&quot;&gt;module&lt;/a&gt;, you will have to add one line of code to your Puppet® codebase to activate basic scanning. When using the &lt;a href=&quot;https://puppet.com/docs/pe/2021.4/osp/the_roles_and_profiles_method.html&quot;&gt;roles and profiles pattern&lt;/a&gt;, and you have a profile that you activate on &lt;strong&gt;all&lt;/strong&gt; of your systems, that would be a good place. You can also add it to your &lt;code class=&quot;highlighter-rouge&quot;&gt;site.pp&lt;/code&gt;. Here is the required line:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Puppet&quot;&gt;include vulnerability
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;When you run Puppet® for the first time after you have added this line, you’ll see something like this:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Notice: /Stage[main]/Vulnerability::Install::Linux/File[/tmp/grype_0.31.1_linux_amd64.tar.gz]/ensure: defined content as '{md5}4bbbf141d3d5f0f2fce319fc31960fab'
Notice: /Stage[main]/Vulnerability::Install::Linux/Exec[extract grype]/returns: executed successfully
Notice: /Stage[main]/Vulnerability::Install::Linux/Exec[cleanup grype download]/returns: executed successfully
Notice: /Stage[main]/Vulnerability::Install::Linux/File[/usr/local/etc/grype_yaml.tpl]/ensure: defined content as '{sha256}45077b3b578c1e665b4d6a9ec94462653145bddd3532cb9c7c5582e15cbc99c9'
Notice: /Stage[main]/Vulnerability::Setup/Fact_config[cve_list]/ttl: defined 'ttl' as '24 hours'
Notice: /Stage[main]/Vulnerability::Setup/File[/usr/local/etc/grype.yaml]/ensure: defined content as '{sha256}5a1a07a3936cb21fa81ec816bfd85a3c0582cb9594b2f6792975471d25593f3a'
Info: /Stage[main]/Vulnerability::Setup/File[/usr/local/etc/grype.yaml]: Scheduling refresh of Fact_cache[cve_list]
Notice: /Stage[main]/Vulnerability::Setup/File[/usr/local/etc/vulnerability.conf]/ensure: defined content as '{sha256}0ab4e8922c550557594b8cb369c130258d1405095c206f9c148225ddc1bcd911'
Info: /Stage[main]/Vulnerability::Setup/File[/usr/local/etc/vulnerability.conf]: Scheduling refresh of Fact_cache[cve_list]
Notice: /Stage[main]/Vulnerability::Update/Exec[Update vulnerability database]/returns: executed successfully
Info: /Stage[main]/Vulnerability::Update/Exec[Update vulnerability database]: Scheduling refresh of Fact_cache[cve_list]
Notice: /Stage[main]/Vulnerability::Clear_facter_cache/Fact_cache[cve_list]: Triggered 'refresh' from 3 events
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This line of Puppet® code, ensure’s that the required software is installed, the default settings are applied, and the vulnerability database is updated. Now Puppet® is all geared up to start scanning your systems.&lt;/p&gt;

&lt;h2 id=&quot;scanning-your-systems&quot;&gt;Scanning your systems&lt;/h2&gt;

&lt;p&gt;Since scanning is fully integrated into your Puppet® workflow, there is nothing extra that you will have to do to start scanning your systems for vulnerabilities. Just run Puppet. On the first tun after installation, you’ll notice that getting the facts for your system takes longer than before. You can see this because of this line:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Info: Loading facts
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Stays a little bit longer on your screen. This is when Puppet® does a full scan of vulnerabilities on your system. Because this is a time-consuming and intensive task, we have preconfigured it to run only once every 24 hours. By default, it scan’s your whole system. You can customize this by either excluding some files and/or directories or only scanning specific directories on your system. Check the &lt;a href=&quot;https://www.enterprisemodules.com/docs/vulnerability/setup.html&quot;&gt;documentation&lt;/a&gt; to see how you can customize this.&lt;/p&gt;

&lt;h2 id=&quot;inspecting-the-vulnerabilities-from-the-command-line&quot;&gt;Inspecting the vulnerabilities from the command-line&lt;/h2&gt;

&lt;p&gt;You can now inspect the vulnerabilities. One way to do this is by using the command-line utility:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ puppet vulnerability list --summary
Critical Vulnerabilities:    0 found.
High Vulnerabilities:        8 found.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;If you would like to see all details, you can use this command:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ puppet vulnerability list --summary --details
{ &quot;CVE-2016-7545&quot;=&amp;gt;
  {&quot;artifact_name&quot;=&amp;gt;&quot;selinux&quot;,
   &quot;version&quot;=&amp;gt;2.9,
   &quot;severity&quot;=&amp;gt;&quot;High&quot;,
   &quot;fix_state&quot;=&amp;gt;&quot;unknown&quot;,
   &quot;locations&quot;=&amp;gt;
    [&quot;/usr/lib64/python3.6/site-packages/selinux-2.9-py3.6.egg-info&quot;]},
 &quot;CVE-2021-0920&quot;=&amp;gt;
  {&quot;artifact_name&quot;=&amp;gt;&quot;python3-perf&quot;,
   &quot;version&quot;=&amp;gt;&quot;4.18.0-348.2.1.el8_5&quot;,
   &quot;severity&quot;=&amp;gt;&quot;High&quot;,
   &quot;fix_state&quot;=&amp;gt;&quot;not-fixed&quot;,
   &quot;locations&quot;=&amp;gt;[&quot;/var/lib/rpm/Packages&quot;]},
   ...
}
Critical Vulnerabilities:    0 found.
High Vulnerabilities:        8 found.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;using-facts-to-manage-the-vulnerabilities&quot;&gt;Using facts to manage the vulnerabilities&lt;/h2&gt;

&lt;h3 id=&quot;on-the-nodes&quot;&gt;On the nodes&lt;/h3&gt;

&lt;p&gt;The integration ensures that the found Vulnerabilities (CVE’s) are available as facts on the system. You can inspect the fact like this:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ puppet facts cve_list
{
  &quot;cve_list&quot;: {
    &quot;CVE-2005-2541&quot;: {
      &quot;artifact_name&quot;: &quot;tar&quot;,
      &quot;fix_state&quot;: &quot;wont-fix&quot;,
      &quot;locations&quot;: [
        &quot;/var/lib/rpm/Packages&quot;
      ],
      &quot;severity&quot;: &quot;Medium&quot;,
      &quot;version&quot;: &quot;2:1.30-5.el8&quot;
    },
    &quot;CVE-2011-1017&quot;: {
      &quot;artifact_name&quot;: &quot;python3-perf&quot;,
      &quot;fix_state&quot;: &quot;wont-fix&quot;,
      &quot;locations&quot;: [
        &quot;/var/lib/rpm/Packages&quot;
      ],
      &quot;severity&quot;: &quot;Medium&quot;,
      &quot;version&quot;: &quot;4.18.0-348.2.1.el8_5&quot;
    },
    ...
    .
    .
    .
  }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Since this information is available to all puppet manifest, you can use this fact to ensure a specific puppet code is applied to your system if a certain CVE is found. This is extremely powerful.&lt;/p&gt;

&lt;h3 id=&quot;on-the-puppetserver&quot;&gt;On the Puppetserver&lt;/h3&gt;

&lt;p&gt;Because it is a regular Puppet® fact, you can also see this on the Puppetserver. Here is a screenshot of inspecting the facts of a specific node on the Puppetserver.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://github.com/enterprisemodules/vulnerability_demo/raw/main/images/puppet-server-facts.jpg&quot; alt=&quot;Facts on the puppetserver&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;guarding-you-systems-agains-vulnerabilities&quot;&gt;Guarding you systems agains vulnerabilities&lt;/h2&gt;

&lt;p&gt;Although all of these ways to inspect your systems for found vulnerabilities, checking this regularly would be taking a lot of time. You would like Puppet® to take care of it and only alert you when more vulnerabilities are found on your system than you bargained for. The vulnerability module had a guarding feature for that. By default, it is deactivated. To activate it, add this line of yaml to your hiera data:&lt;/p&gt;

&lt;div class=&quot;language-yaml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;s&quot;&gt;vulnerability::guard&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;                     &lt;span class=&quot;no&quot;&gt;false&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Next, you will have to tell Puppet® when to alarm you. Again you can use hiera to add these settings:&lt;/p&gt;

&lt;div class=&quot;language-yaml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;s&quot;&gt;vulnerability::guard::critical&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;           &lt;span class=&quot;s&quot;&gt;0&lt;/span&gt;   &lt;span class=&quot;c1&quot;&gt;# Alert me when 1 or more Critical vulnerabilities are found&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;vulnerability::guard::high&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;               &lt;span class=&quot;s&quot;&gt;2&lt;/span&gt;   &lt;span class=&quot;c1&quot;&gt;# Alert me when2 or more High vulnerabilities are found&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;vulnerability::guard::medium&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;             &lt;span class=&quot;s&quot;&gt;~&lt;/span&gt;   &lt;span class=&quot;c1&quot;&gt;# I don't care about the medium vulnerabilities&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;vulnerability::guard::allow_list&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;GHSA-gpvv-69j7-gwj8&lt;/span&gt;                   &lt;span class=&quot;c1&quot;&gt;# I know about the GHSA-gpvv-69j7-gwj8 vulnerabiliy and I don't mind&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Now on every Puppet® run, Puppet® will guard the number of found vulnerabilities and alert you when more are found on the system:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Notice: /Stage[main]/Vulnerability::Guard/Vulnerability_status[puppetserver.example.com]/high: high changed 7 to 2
Error: /Stage[main]/Vulnerability::Guard/Vulnerability_status[puppetserver.example.com]: Could not evaluate: More high vulnerabilities found than specified value 2 on puppetserver.example.com; actual found is: 7.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id=&quot;remediating&quot;&gt;Remediating&lt;/h2&gt;

&lt;p&gt;Since all of the vulnerability information is available as a fact, you can easily write Puppet® code to remediate any found vulnerabilities. Here is a straightforward example:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Puppet&quot;&gt;# @summary Resolve CVE-2021-43527
#
# Resolve the CVE-2021-43527 by updating the nss-tools package to
# the latest version. 
#
class resolve::cve_2021_43527 {

  if vulnerability::detect('CVE-2021-43527') {
    package {'nss-tools':
      ensure =&amp;gt; 'latest',
      notify =&amp;gt; fact_cache['cve_list']
    }
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This Puppet® code check’s the &lt;code class=&quot;highlighter-rouge&quot;&gt;cve_list&lt;/code&gt; fact if vulnerability &lt;code class=&quot;highlighter-rouge&quot;&gt;CVE-2021-43527&lt;/code&gt; is on your system and resolves the vulnerability by installing the latest version of the &lt;code class=&quot;highlighter-rouge&quot;&gt;nss-tools&lt;/code&gt; package.&lt;/p&gt;

&lt;h2 id=&quot;puppet-to-resolve-vulnerabilities&quot;&gt;Puppet® to resolve vulnerabilities&lt;/h2&gt;

&lt;p&gt;We are in the process of publishing an open-source module containing Puppet® remediation code for many vulnerabilities. Since it is open-source, the community can help extend it so everybody can use this to quickly and safely resolve any of your vulnerabilities. Stay tuned for more information about this module.&lt;/p&gt;

&lt;h2 id=&quot;more-information&quot;&gt;More information&lt;/h2&gt;

&lt;p&gt;You can find more information about Puppet® vulnerability scanning here:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.enterprisemodules.com/news/2021/12/detecting-and-resolving-vulnerabilities-with-puppet/&quot;&gt;Detecting and resolving vulnerabilities with Puppet®&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;/docs/vulnerability/description.html&quot;&gt;Module documentation&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Some example code:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;[/docs/vulnerability/description.html](https://github.com/enterprisemodules/vulnerability_demo)&quot;&gt;Vulnerability demo&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;interested&quot;&gt;Interested?&lt;/h2&gt;

&lt;p&gt;We hope this article has shown you the benefits of integrating vulnerability management into your Puppet® workflow and how easy it is to get it up and running. We know some of the vulnerability scanning tools out there are expensive. Besides being very efficient and easy, we have made sure that vulnerability scanning is very affordable. &lt;a href=&quot;https://www.enterprisemodules.com/company/contact/&quot;&gt;Contact us&lt;/a&gt; if you want more information.&lt;/p&gt;

&lt;p&gt;If you want to know more, please check out the documentation of these modules &lt;a href=&quot;hhttps://www.enterprisemodules.com/docs/vulnerability/description.html&quot;&gt;here&lt;/a&gt; for more information about this module and all the possibilities. If you are just starting, check out our &lt;strong&gt;FREE&lt;/strong&gt; &lt;a href=&quot;/business-benefits/free-trial-license/&quot;&gt;trial license&lt;/a&gt; to get going.&lt;/p&gt;

&lt;h2 id=&quot;about-us&quot;&gt;About us&lt;/h2&gt;

&lt;p&gt;Enterprise modules is the leading developer of enterprise-ready Puppet® modules for Oracle databases,Oracle WebLogic, and IBM MQ 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.&lt;/p&gt;
</description><pubDate>Fri, 14 Jan 2022 00:00:00 +0100</pubDate><link>https://www.enterprisemodules.com/blog/2022/01/vulnerability-management-with-puppet/</link><guid isPermaLink="true">https://www.enterprisemodules.com/blog/2022/01/vulnerability-management-with-puppet/</guid><category>puppet</category><category>vulnerability</category><category>security</category><category>blog</category><category>puppet</category><category>security</category></item><item><title>A solution for Puppet® hiera yaml sprawl</title><description>&lt;p&gt;&lt;img src=&quot;/post-images/include-yaml.jpg&quot; alt=&quot;A solution for Puppet® hiera yaml sprawl&quot; /&gt;
hiera is a very powerful way to separate code and data in Puppet® code. But sometimes, you need more than the standard functionality for levels that hiera provides. One way to keep configuration data from being duplicated over multiple levels would be to include other yaml files. Unfortunately, yaml doesn’t have any means to do this. That is why we built an extended yaml hiera backend that allows you to do this.&lt;/p&gt;

&lt;h2 id=&quot;a-use-case-for-yaml-include&quot;&gt;A use case for yaml include&lt;/h2&gt;

&lt;p&gt;One of the use cases that we run into regularly with our clients, is doing version upgrades of for example Oracle software. We have one role yaml that contains all of the hiera data needed to ensure a correct Oracle database is built and configured by Puppet. Here is an excerpt of such a yaml file:&lt;/p&gt;

&lt;div class=&quot;language-yaml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;s&quot;&gt;ora_profile::database::dbname&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;                  &lt;span class=&quot;s&quot;&gt;MYDB&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;ora_profile::database::version&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;                 &lt;span class=&quot;s&quot;&gt;19.0.0.0&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;ora_profile::database::db_patches::patch_level&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;JUL2021RU&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;ora_profile::database::oracle_home&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;             &lt;span class=&quot;s&quot;&gt;/u01/app/oracle/product/19.0.0.0/db_home1&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;ora_profile::database::db_software::file_name&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;  &lt;span class=&quot;s&quot;&gt;LINUX.X64_193000_db_home&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;ora_profile::database::db_software::dirs&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
&lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;/u01/app/oracle/product&lt;/span&gt;
&lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;/u01/app/oracle/product/DB19&quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;As you can see, this yaml file contains some references to the version used. In this case, Oracle 19.&lt;/p&gt;

&lt;p&gt;When we want to start using Oracle 21, however, we want to do this gradually. So first on one development machine and then on more or even on all development machines and then through testing and acceptance finally to production. One of the ways to do this is to add the updated hiera data to the node-specific hiera levels. This allows you to start rolling out Oracle 21 controlled on a node-by-node basis. This, however leads to a sprawl of hiera entries throughout your yaml files. Wouldn’t it be great if you could include a file containing all entries for a specific version? Yes, you can!!&lt;/p&gt;

&lt;h2 id=&quot;how-does-it-look&quot;&gt;How does it look?&lt;/h2&gt;

&lt;p&gt;Here is how this looks in a yaml file:&lt;/p&gt;

&lt;div class=&quot;language-yaml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nn&quot;&gt;---&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;some::other::data&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;  &lt;span class=&quot;s&quot;&gt;yes&lt;/span&gt;
&lt;span class=&quot;nn&quot;&gt;...&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# @include '../includes/oracle_21.yaml'&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;#&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;other::entry::in::your:yaml&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;	&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;just_some value&lt;/span&gt;
&lt;span class=&quot;nn&quot;&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This little snippet will include the file &lt;code class=&quot;highlighter-rouge&quot;&gt;oracle_21.yaml&lt;/code&gt; from the directory &lt;code class=&quot;highlighter-rouge&quot;&gt;includes&lt;/code&gt; below the directory of the current yaml file into your current yaml file.&lt;/p&gt;

&lt;p&gt;The include process itself replaces the include line with the content of the included files and then passes it to the Ruby yaml processor as one entity.&lt;/p&gt;

&lt;p&gt;But why is it a comment (e.g. behind a #)? The reson for this, is that many Puppet® CI tools check the validity of yaml files. If we would have put the include as a “normal” stratement, all of the CI checks for yaml will fail. That is not what we want.&lt;/p&gt;

&lt;h2 id=&quot;how-do-we-enable-this&quot;&gt;How do we enable this?&lt;/h2&gt;

&lt;p&gt;The hiera backend is called &lt;code class=&quot;highlighter-rouge&quot;&gt;easy_type::yaml_with_include&lt;/code&gt; and as the name implies, it is part of the &lt;code class=&quot;highlighter-rouge&quot;&gt;easy_type&lt;/code&gt; module. The &lt;a href=&quot;https://forge.puppet.com/modules/enterprisemodules/easy_type&quot;&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;enterprisemodules-easy_type&lt;/code&gt; module&lt;/a&gt; is a collection of functions, custom types and other Puppet® goodies we use for all of our commercial modules. You are free to install and use it.  Check the documentation on the &lt;a href=&quot;https://forge.puppet.com/modules/enterprisemodules/easy_type&quot;&gt;Puppet forge&lt;/a&gt; on how to install this module into your Puppet® code base.&lt;/p&gt;

&lt;p&gt;After the installation, we have to configure hiera to use it. The easiest way to do this is to replace the defaults in your &lt;code class=&quot;highlighter-rouge&quot;&gt;hiera.yaml&lt;/code&gt; file. We need to change the value for the &lt;code class=&quot;highlighter-rouge&quot;&gt;data_hash&lt;/code&gt; key from &lt;code class=&quot;highlighter-rouge&quot;&gt;yaml_data&lt;/code&gt; to &lt;code class=&quot;highlighter-rouge&quot;&gt;easy_type::yaml_with_include&lt;/code&gt;. Here is an example of how your &lt;code class=&quot;highlighter-rouge&quot;&gt;hiera.yaml&lt;/code&gt; could look.&lt;/p&gt;

&lt;div class=&quot;language-yaml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nn&quot;&gt;---&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;version&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;5&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;defaults&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;# Used for any hierarchy level that omits these keys.&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;datadir&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;hieradata&lt;/span&gt;                          &lt;span class=&quot;c1&quot;&gt;# This path is relative to hiera.yaml's directory.&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;data_hash&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;easy_type::yaml_with_include&lt;/span&gt;  

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;lets-try-it&quot;&gt;Let’s try it.&lt;/h2&gt;

&lt;p&gt;Our role yaml now contains the include statement &lt;code class=&quot;highlighter-rouge&quot;&gt;# @include '../includes/oracle_21.yaml'. Our &lt;/code&gt;oracle_21.yaml` file looks like this:&lt;/p&gt;

&lt;div class=&quot;language-yaml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;s&quot;&gt;ora_profile::database::version&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;                  &lt;span class=&quot;s&quot;&gt;21.0.0.0&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;ora_profile::database::db_patches::patch_level&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;  &lt;span class=&quot;s&quot;&gt;JUL2021RU&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;ora_profile::database::oracle_home&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;              &lt;span class=&quot;s&quot;&gt;/u01/app/oracle/product/21.0.0.0/db_home1&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;ora_profile::database::db_software::file_name&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;   &lt;span class=&quot;s&quot;&gt;LINUX.X64_213000_db_home&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;ora_profile::database::db_software::dirs&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
&lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;/u01/app/oracle/product&lt;/span&gt;
&lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;/u01/app/oracle/product/DB21&quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The best way to check if it works and also to debug lookups, is to use the &lt;code class=&quot;highlighter-rouge&quot;&gt;puppet lookup&lt;/code&gt; utility.  Let’s use this utility to lookup the version of Oracle.&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ puppet lookup ora_profile::database::version
--- 21.0.0.0
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;And it works. But it would be nice to get a bit more details. Fortunately, the &lt;code class=&quot;highlighter-rouge&quot;&gt;puppet lookup&lt;/code&gt; utility has a way of explaining what it does. Let’s try again and use the &lt;code class=&quot;highlighter-rouge&quot;&gt;--explain&lt;/code&gt; option:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ puppet lookup ora_profile::database::version --explain

...

  Environment Data Provider (hiera configuration version 5)
    Using configuration &quot;/etc/puppetlabs/code/environments/production/hiera.yaml&quot;
    Merge strategy hash
      Hierarchy entry &quot;Per-node data&quot;
        Merge strategy hash
          Path &quot;/etc/puppetlabs/code/environments/production/hieradata/nodes/db190.example.com.yaml&quot;
            Original path: &quot;nodes/%{trusted.certname}.yaml&quot;
            No such key: &quot;lookup_options&quot;
            Including file '/etc/puppetlabs/code/environments/production/hieradata/includes/oracle_21.yaml' into contents of '/etc/puppetlabs/code/environments/production/hieradata/nodes/db190.example.com.yaml'
          Path &quot;/etc/puppetlabs/code/environments/production/hieradata/nodes/db190.yaml&quot;
            Original path: &quot;nodes/%{hostname}.yaml&quot;
            Path not found

...

Searching for &quot;ora_profile::database::version&quot;
  Global Data Provider (hiera configuration version 5)
    Using configuration &quot;/etc/puppetlabs/puppet/hiera.yaml&quot;
    No such key: &quot;ora_profile::database::version&quot;
  Environment Data Provider (hiera configuration version 5)
    Using configuration &quot;/etc/puppetlabs/code/environments/production/hiera.yaml&quot;
    Hierarchy entry &quot;Per-node data&quot;
      Path &quot;/etc/puppetlabs/code/environments/production/hieradata/nodes/db190.example.com.yaml&quot;
        Original path: &quot;nodes/%{trusted.certname}.yaml&quot;
        Found key: &quot;ora_profile::database::version&quot; value: &quot;21.0.0.0&quot;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;As you can see by the line &lt;code class=&quot;highlighter-rouge&quot;&gt;/etc/puppetlabs/code/environments/production/hieradata/includes/oracle_21.yaml' into contents of '/etc/puppetlabs/code/environments/production/hieradata/nodes/db190.example.com.yaml'&lt;/code&gt; hiera tells you it is including the file. It only notifies you once. Because for performance reasons, it only reads the files one time. Every additional hiera lookup will use the cached data and not know anything about the inclusion of the file.&lt;/p&gt;

&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;When sprawl of hiera data over your many hiera levels is an issue for you, we have a way to help you. The &lt;code class=&quot;highlighter-rouge&quot;&gt;yaml_with_include&lt;/code&gt; hiera backend allows you to use include statements in your hiera yaml data. We hope this will help you. 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 &lt;a href=&quot;https://www.enterprisemodules.com/company/contact/&quot;&gt;contact us&lt;/a&gt; at &lt;a href=&quot;mailto:info@enterprisemodules.com&quot;&gt;info@enterprisemodules.com&lt;/a&gt; or by phone: +31 (0)653 847 326 for some consultancy.&lt;/p&gt;

&lt;h2 id=&quot;about-us&quot;&gt;About us&lt;/h2&gt;

&lt;p&gt;Enterprise modules is the leading developer of enterprise-ready Puppet® modules for Oracle databases,Oracle WebLogic, and IBM MQ 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.&lt;/p&gt;
</description><pubDate>Wed, 20 Oct 2021 00:00:00 +0200</pubDate><link>https://www.enterprisemodules.com/blog/2021/10/a-solution-for-puppet-hiera-yaml-sprawl/</link><guid isPermaLink="true">https://www.enterprisemodules.com/blog/2021/10/a-solution-for-puppet-hiera-yaml-sprawl/</guid><category>puppet</category><category>blog</category><category>puppet</category></item><item><title>Dynamic but versioned hiera data with git</title><description>&lt;p&gt;&lt;img src=&quot;/post-images/dynamic-hiera.jpg&quot; alt=&quot;Dynamic but versioned hiera data with git&quot; /&gt;
For some organizations, having dynamic hiera data can be a real time saver. Add a small change to your hiera data; there is no need for a Puppet® redeploys, and off you go. Although this is fast, it has some potential downsides too.  You cannot see who did this change and why and when it was done.  Fortunately, there is a way around some of these downsides.&lt;/p&gt;

&lt;h2 id=&quot;there-is-a-module-for-that&quot;&gt;There is a module for that&lt;/h2&gt;

&lt;p&gt;On the puppetforge there is a module called &lt;a href=&quot;https://forge.puppet.com/modules/crayfishx/hiera_http&quot;&gt;hiera_http&lt;/a&gt; that can help us implement this. This module implements a hiera backend that can connect to any http endpoint. It can read yaml and json data. You can tell the hiera backend for what hiera keys this backend is used.&lt;/p&gt;

&lt;h2 id=&quot;our-use-case&quot;&gt;Our use case&lt;/h2&gt;

&lt;p&gt;Our use case for this solution is the definition of available patches. These patches are currently defined in the module hiera data of our module &lt;a href=&quot;https://forge.puppet.com/modules/enterprisemodules/ora_profile&quot;&gt;ora_profile&lt;/a&gt;. So whenever a new patch level comes available, we update the hiera data in this module and publish a new version of the module for our customers to use. However, some customers don’t want to update this module so often. A new version of a module might not only contain updated data, but it might also contain incompatible Puppet® code and at least require organizations to do some testing. So for these customers, we would like to allow them to &lt;strong&gt;only&lt;/strong&gt; use the updated patch-levels in the hiera data but still keep on using the version of the module they currently have.  They could, of course, copy the definitions of the patches to their own hiera files. But this means some extra maintenance burden on your internal team. The solution we have in mind is to allow customers to use the latest version of the hiera data without the need to install the newest version.&lt;/p&gt;

&lt;h2 id=&quot;how-to-make-it-work&quot;&gt;How to make it work&lt;/h2&gt;

&lt;p&gt;Let’s first make sure that the module and all its prerequisites are installed.
As the documentation states, the &lt;code class=&quot;highlighter-rouge&quot;&gt;lookup_http&lt;/code&gt; gem must be installed. Here is the command to do this for your puppet server.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;puppetserver gem &lt;span class=&quot;nb&quot;&gt;install &lt;/span&gt;lookup_http
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;When you are using the &lt;code class=&quot;highlighter-rouge&quot;&gt;puppet lookup&lt;/code&gt; feature, you’ll also need to install this gem for the ruby context outside of the puppetserver.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;/opt/puppetlabs/puppet/bin/gem &lt;span class=&quot;nb&quot;&gt;install &lt;/span&gt;lookup_http
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Next up is the installation of the module itself. You can do this manual with this command:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;puppet module install crayfishx/hiera_http
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;A better way is to use a Puppetfile and add this line to it:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;mod 'crayfishx-hiera_http', 'x.x.x'
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;and then use the puppet deployments to ensure&lt;/p&gt;

&lt;h2 id=&quot;what-data-to-use&quot;&gt;What data to use&lt;/h2&gt;

&lt;p&gt;Now the essential tasks of installation are done, let’s focus on the configuration. We need to tell the hiera backend that it must use a github url to fetch the data. Here is part of the &lt;code class=&quot;highlighter-rouge&quot;&gt;hiera.yaml&lt;/code&gt; that defines the hiera search levels.&lt;/p&gt;

&lt;div class=&quot;language-yaml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;na&quot;&gt;hierarchy&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
 &lt;span class=&quot;s&quot;&gt;….&lt;/span&gt; 
 &lt;span class=&quot;s&quot;&gt;- name&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;Dynamic&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;patches&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;lookup&quot;&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;lookup_key&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;hiera_http&lt;/span&gt;
   &lt;span class=&quot;na&quot;&gt;uris&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
     &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;https://raw.githubusercontent.com/enterprisemodules/ora_profile/master/data/defaults.yaml&lt;/span&gt;
   &lt;span class=&quot;na&quot;&gt;options&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
     &lt;span class=&quot;na&quot;&gt;output&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;yaml&lt;/span&gt;
     &lt;span class=&quot;na&quot;&gt;use_ssl&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;true&lt;/span&gt;
     &lt;span class=&quot;na&quot;&gt;confine_to_keys&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; 
        &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;ora_profile::database::patch_levels&lt;/span&gt;
 
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Let me take you through some of the options:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;uris&lt;/code&gt;: This is the url where the backend will fetch the data. You can get this url by going to the repository in github and open the file you want to use.  Then select the &lt;code class=&quot;highlighter-rouge&quot;&gt;raw&lt;/code&gt; button, and github will take you to a raw version of this data file. You can copy the url and put it in your &lt;code class=&quot;highlighter-rouge&quot;&gt;hiera.yaml&lt;/code&gt;. For our use case, we use the main branch. But you can also select a specific branch, tag, or even commit.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;output&lt;/code&gt;: In our use-case, the file we selected is a yaml file, so we want the backend to interpret the data as yaml data.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;use_ssl&lt;/code&gt;:  Although the backend &lt;em&gt;should&lt;/em&gt; be able to detect itself if this is a &lt;code class=&quot;highlighter-rouge&quot;&gt;https&lt;/code&gt; or &lt;code class=&quot;highlighter-rouge&quot;&gt;http&lt;/code&gt; url, we need to set the value to &lt;code class=&quot;highlighter-rouge&quot;&gt;true&lt;/code&gt; when using a &lt;code class=&quot;highlighter-rouge&quot;&gt;https&lt;/code&gt; url,&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;confine_to_keys&lt;/code&gt;: We &lt;strong&gt;only&lt;/strong&gt; want to enable the patch level through this mechanism in our use-case. So we specify only one key, namely the key &lt;code class=&quot;highlighter-rouge&quot;&gt;ora_profile::database::patch_levels&lt;/code&gt;. All other hiera keys will be resolved through the other hiera levels and, in this case, be resolved from the module data of the current version of the installed module. You can, however, add multiple keys, and you can also use regular expressions like for example : &lt;code class=&quot;highlighter-rouge&quot;&gt;&quot;application.*&quot;&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h1 id=&quot;test-it&quot;&gt;test it&lt;/h1&gt;

&lt;p&gt;Now everything should be set up correctly, and we are ready to test. You can, of course, just run the Puppet® agent and see if it works, but it can be difficult to distinguish between already available hiera-data in the module and the dynamic data from git. Therefore I’d like to use the &lt;code class=&quot;highlighter-rouge&quot;&gt;puppet lookup --explain&lt;/code&gt; command. This command does the lookup and explains what actions hiera takes on each hiera level.&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ puppet lookup ora_profile::database::patch_levels  --explain
/etc/puppetlabs/code/environments/production/modules/hiera_http/lib/puppet/functions/hiera_http.rb:105: warning: URI.escape is obsolete
Searching for &quot;lookup_options&quot;
  Global Data Provider (hiera configuration version 5)
    Using configuration &quot;/etc/puppetlabs/puppet/hiera.yaml&quot;
...[some output deleted]
       Hierarchy entry &quot;Dynamic patches lookup&quot;
          URI &quot;https://raw.githubusercontent.com/enterprisemodules/ora_profile/master/data/defaults.yaml&quot;
            Original uri: &quot;https://raw.githubusercontent.com/enterprisemodules/ora_profile/master/data/defaults.yaml&quot;
            Found key: &quot;ora_profile::database::patch_levels&quot; value: {
...[some output deleted]
...
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;As you can see, the &lt;code class=&quot;highlighter-rouge&quot;&gt;Hierarchy entry &quot;Dynamic patches lookup&quot;&lt;/code&gt; returned the data, so it works.&lt;/p&gt;

&lt;h2 id=&quot;gotchas&quot;&gt;Gotchas&lt;/h2&gt;

&lt;p&gt;In this use case, we only fetch reference data. This means that any change to this data doesn’t directly change the Puppet® catalog. It allows you to use a different patch level in your manifest. &lt;strong&gt;Only&lt;/strong&gt; after you change the patch level in your Puppet® manifest for this node, the patch level will be applied. We like this because it means your system can only change &lt;strong&gt;after&lt;/strong&gt; a Puppet® deploy, and not all of a sudden show changes. For some use cases, however, this is precisely what people like and need.&lt;/p&gt;

&lt;p&gt;Your hiera data can contain lookups in its data. For example:&lt;/p&gt;

&lt;div class=&quot;language-yaml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;na&quot;&gt;my_key&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;%{lookup('other_key'}&quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;When your hiera data contains this, beware that the &lt;code class=&quot;highlighter-rouge&quot;&gt;other_key&lt;/code&gt; resolves from the same source version. Else you can get very nasty and brutal to find errors.&lt;/p&gt;

&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;In this blog post, we have shown you how to add dynamic hiera data to your Puppet® environment. Dynamic but still versioned, so you are still in control. Your use case might be slightly different, so if you need some help, don’t hesitate to &lt;a href=&quot;https://www.enterprisemodules.com/company/contact/&quot;&gt;contact us&lt;/a&gt; at &lt;a href=&quot;mailto:info@enterprisemodules.com&quot;&gt;info@enterprisemodules.com&lt;/a&gt; or by phone: +31 (0)653 847 326
for some consultancy.&lt;/p&gt;

&lt;h2 id=&quot;about-us&quot;&gt;About us&lt;/h2&gt;

&lt;p&gt;Enterprise modules is the leading developer of enterprise-ready Puppet® modules for Oracle databases,Oracle WebLogic, and IBM MQ 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.&lt;/p&gt;

</description><pubDate>Fri, 01 Oct 2021 00:00:00 +0200</pubDate><link>https://www.enterprisemodules.com/blog/2021/10/dynamic-but-versioned-hiera-data-with-git/</link><guid isPermaLink="true">https://www.enterprisemodules.com/blog/2021/10/dynamic-but-versioned-hiera-data-with-git/</guid><category>puppet</category><category>blog</category><category>puppet</category></item><item><title>Gain control of your MQ versions and fixpacks</title><description>&lt;p&gt;&lt;img src=&quot;/post-images/mq-puppet.jpg&quot; alt=&quot;Using Puppet® to (re)gain control of your MQ versions and fixpacks&quot; /&gt;
Many larger organizations use the IBM MQ as messaging middleware. Sometimes the IT infrastructure needed to run MQ can span a large number of nodes. This large number of nodes increases the issue of ensuring all systems run a correct fixpack or even a correct version of the MQ software. Having MQ running on multiple operating systems like AIX, Linux, Solaris, and Windows increases the complexity of this problem.&lt;/p&gt;

&lt;p&gt;Using a combination of Puppet’s desired state and Puppet® tasks, you can easily (re)gain control of your MQ versions and fixpacks on a large fleet of systems using multiple operating systems.&lt;/p&gt;

&lt;h2 id=&quot;puppet-desired-state-language&quot;&gt;Puppet® Desired State Language&lt;/h2&gt;

&lt;p&gt;The most known feature of Puppet® is the Puppet® desired state management. With this feature, you specify &lt;strong&gt;how&lt;/strong&gt; a system should be configured using the Puppet® language.  The Puppet® language allows you to specify certain external data. This is called &lt;a href=&quot;https://puppet.com/docs/puppet/7/hiera_intro.html&quot;&gt;hiera&lt;/a&gt;. Our &lt;a href=&quot;https://www.enterprisemodules.com/shop/t/technology/ibm&quot;&gt;Puppet IBM modules&lt;/a&gt; use this feature extensively.&lt;/p&gt;

&lt;p&gt;Here is an example of the hiera data you can use to specify a particular MQ version and fixpack.&lt;/p&gt;

&lt;div class=&quot;language-yaml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;s&quot;&gt;mq_install::fixpack::service_window:&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;			&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;   DIRECT&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;ibm_profile::mq_machine::software::version&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;  &lt;span class=&quot;s&quot;&gt;9.1.0.0&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;ibm_profile::mq_machine::fixpack::version&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;   &lt;span class=&quot;s&quot;&gt;9.1.0.7&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;When puppet run’s on a newly installed system, the part of the output that installs the MQ software looks like this:&lt;/p&gt;
&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Notice: /Stage[main]/Mq_install::Software/Mq_install::Software::Unix[mq_installation_9.1.0.0]/Archive[/tmp/IBM_MQ_9.1.0.0_LINUX_X86-64.tar.gz]/ensure: download archive from /vagrant/modules/software/files/IBM_MQ_9.1.0.0_LINUX_X86-64.tar.gz to /tmp/IBM_MQ_9.1.0.0_LINUX_X86-64.tar.gz and extracted in /tmp with cleanup
Notice: /Stage[main]/Mq_install::Software/Mq_install::Software::Unix[mq_installation_9.1.0.0]/Exec[Accept MQ License Requirements]/returns: executed successfully
Notice: /Stage[main]/Mq_install::Software/Mq_install::Software::Unix[mq_installation_9.1.0.0]/Package[MQSeriesRuntime-9.1.0-0]/ensure: created
Notice: /Stage[main]/Mq_install::Software/Mq_install::Software::Unix[mq_installation_9.1.0.0]/Package[MQSeriesJRE-9.1.0-0]/ensure: created
Notice: /Stage[main]/Mq_install::Software/Mq_install::Software::Unix[mq_installation_9.1.0.0]/Package[MQSeriesJava-9.1.0-0]/ensure: created
Notice: /Stage[main]/Mq_install::Software/Mq_install::Software::Unix[mq_installation_9.1.0.0]/Package[MQSeriesServer-9.1.0-0]/ensure: created
Notice: /Stage[main]/Mq_install::Software/Mq_install::Software::Unix[mq_installation_9.1.0.0]/File[Remove temporary files]/ensure: removed
Notice: /Stage[main]/Mq_install::Fixpack/File[/tmp/mq_fixpack_9.1.0.7]/ensure: created
Notice: /Stage[main]/Mq_install::Fixpack/Archive[/tmp/9.1.0-IBM-MQ-LinuxX64-FP0007.tar.gz]/ensure: download archive from puppet:///modules/software/9.1.0-IBM-MQ-LinuxX64-FP0007.tar.gz to /tmp/9.1.0-IBM-MQ-LinuxX64-FP0007.tar.gz and extracted in /tmp/mq_fixpack_9.1.0.7 with cleanup
Notice: /Stage[main]/Mq_install::Fixpack/Mq_install::Internal::Mq_packages[U9107-9.1.0-7]/Package[MQSeriesRuntime-U9107-9.1.0-7]/ensure: created
Notice: /Stage[main]/Mq_install::Fixpack/Mq_install::Internal::Mq_packages[U9107-9.1.0-7]/Package[MQSeriesJRE-U9107-9.1.0-7]/ensure: created
Notice: /Stage[main]/Mq_install::Fixpack/Mq_install::Internal::Mq_packages[U9107-9.1.0-7]/Package[MQSeriesJava-U9107-9.1.0-7]/ensure: created
Notice: /Stage[main]/Mq_install::Fixpack/Mq_install::Internal::Mq_packages[U9107-9.1.0-7]/Package[MQSeriesServer-U9107-9.1.0-7]/ensure: created
Notice: /Stage[main]/Mq_install::Fixpack/Exec[Remove temporary files for fixpack 9.1.0.7]/returns: executed successfully
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;As you can see, all steps needed to fetch the MQ software and fixpack and actions required to install them are automated. Because Puppet® uses &lt;a href=&quot;https://puppet.com/docs/puppet/7/puppet_overview.html#key_concepts_puppet-idempotency&quot;&gt;idempotency&lt;/a&gt;, on a second Puppet® run, Puppet® detects that the correct versions are installed, and Puppet® will do nothing.&lt;/p&gt;

&lt;h2 id=&quot;performing-a-fixpack-update&quot;&gt;Performing a fixpack update&lt;/h2&gt;

&lt;p&gt;If a system has been provisioned previously with the hiera data displayed above, The system will be running MQ 9.1.0.7. If we want to update to fixpack 8 (e.g., version 9.1.0.8), we only need to change the hiera data. Here is how it needs to look.&lt;/p&gt;

&lt;div class=&quot;language-yaml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;s&quot;&gt;mq_install::fixpack::service_window:&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;			&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;   DIRECT&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;ibm_profile::mq_machine::software::version&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;  &lt;span class=&quot;s&quot;&gt;9.1.0.0&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;ibm_profile::mq_machine::fixpack::version&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;   &lt;span class=&quot;s&quot;&gt;9.1.0.8&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;If Puppet® now runs on this system, it determines that you have specified a newer version of the fixpack. Because the &lt;code class=&quot;highlighter-rouge&quot;&gt;service_window&lt;/code&gt; parameter is set to &lt;code class=&quot;highlighter-rouge&quot;&gt;DIRECT,&lt;/code&gt; it will immediately shut down MQ and apply the required fixpack. After the upgrade is done, Puppet® will automatically restart all previously running MQ queue managers.&lt;/p&gt;

&lt;p&gt;Here is some example output:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Notice: /Stage[main]/Mq_install::Internal::Mq_stop/Exec[Stop MQ manager QM01]/returns: executed successfully
Notice: /Stage[main]/Mq_install::Fixpack/Mq_install::Internal::Mq_packages[U9108-9.1.0-8]/Package[MQSeriesRuntime-U9108-9.1.0-8]/ensure: created
Notice: /Stage[main]/Mq_install::Fixpack/Mq_install::Internal::Mq_packages[U9108-9.1.0-8]/Package[MQSeriesJRE-U9108-9.1.0-8]/ensure: created
Notice: /Stage[main]/Mq_install::Fixpack/Mq_install::Internal::Mq_packages[U9108-9.1.0-8]/Package[MQSeriesJava-U9108-9.1.0-8]/ensure: created
Notice: /Stage[main]/Mq_install::Fixpack/Mq_install::Internal::Mq_packages[U9108-9.1.0-8]/Package[MQSeriesServer-U9108-9.1.0-8]/ensure: created
Notice: /Stage[main]/Mq_install::Fixpack/Exec[Remove temporary files for fixpack 9.1.0.8]/returns: executed successfully
Notice: /Stage[main]/Ibm_profile::Mq_machine::Manager_setup/Mq_manager[QM01]/status: status changed 'Ended normally' to 'Running'
Notice: /Stage[main]/Ibm_profile::Mq_machine::Autostart/Mq_install::Autostart[QM01]/Exec[stop QM01 running outside systemd]/returns: executed successfully
Notice: /Stage[main]/Ibm_profile::Mq_machine::Autostart/Mq_install::Autostart[QM01]/Service[mq@QM01]/ensure: ensure changed 'stopped' to 'running'
Info: /Stage[main]/Ibm_profile::Mq_machine::Autostart/Mq_install::Autostart[QM01]/Service[mq@QM01]: Unscheduling refresh on Service[mq@QM01]
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;On the next  Puppet® run, Puppet® will detect that the correct versions are installed, and Puppet® will do nothing.&lt;/p&gt;

&lt;h2 id=&quot;oh-oh-issues&quot;&gt;Oh Oh, issues&lt;/h2&gt;

&lt;p&gt;Although you have prepared everything meticulously, sometimes things go wrong, and you have to roll back to the previous.  Fortunately, Puppet® can help you here too: Just change the hiera data back and run Puppet® again.&lt;/p&gt;

&lt;p&gt;Here is the example output.&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Notice: /Stage[main]/Mq_install::Internal::Mq_stop/Exec[Stop MQ manager QM01]/returns: executed successfully
Notice: /Stage[main]/Mq_install::Fixpack/Exec[uninstall fixpack U9108]/returns: executed successfully
Notice: /Stage[main]/Ibm_profile::Mq_machine::Manager_setup/Mq_manager[QM01]/status: status changed 'Ended normally' to 'Running'
Notice: /Stage[main]/Ibm_profile::Mq_machine::Autostart/Mq_install::Autostart[QM01]/Exec[stop QM01 running outside systemd]/returns: executed successfully
Notice: /Stage[main]/Ibm_profile::Mq_machine::Autostart/Mq_install::Autostart[QM01]/Service[mq@QM01]/ensure: ensure changed 'stopped' to 'running'
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;As you can see, fixpack &lt;code class=&quot;highlighter-rouge&quot;&gt;U9108&lt;/code&gt; is uninstalled, and the situation is back to before the fixpack update.&lt;/p&gt;

&lt;h2 id=&quot;performing-a-major-update&quot;&gt;Performing a major update&lt;/h2&gt;

&lt;p&gt;At this point in time, MQ version 9.2 is the latest. Let’s update the systems to this version. Here is the required hiera data.&lt;/p&gt;

&lt;div class=&quot;language-yaml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;s&quot;&gt;mq_install::software::service_window&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;        &lt;span class=&quot;s&quot;&gt;DIRECT&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;ibm_profile::mq_machine::software::version&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;  &lt;span class=&quot;s&quot;&gt;9.2.0.0&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# ibm_profile::mq_machine::fixpack::version: This needs to unset when no fixpack is installed&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The process is the same as with the installation of a fixpack. Puppet® determines that you have requested a new major version. It will shut down all running MQ managers, uninstall the old software, install the new major version and start the queue managers again.&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Notice: /Stage[main]/Mq_install::Internal::Mq_stop/Exec[Stop MQ manager QM01]/returns: executed successfully
Notice: /Stage[main]/Mq_install::Software/Mq_install::Software::Unix[mq_installation_9.2.0.0]/Exec[uninstall RPMS for version 9.1.0.7]/returns: executed successfully
Notice: /Stage[main]/Mq_install::Software/Mq_install::Software::Unix[mq_installation_9.2.0.0]/Archive[/tmp/IBM_MQ_9.2.0_LINUX_X86-64.tar.gz]/ensure: download archive from /vagrant/modules/software/files/IBM_MQ_9.2.0_LINUX_X86-64.tar.gz to /tmp/IBM_MQ_9.2.0_LINUX_X86-64.tar.gz and extracted in /tmp with cleanup
Notice: /Stage[main]/Mq_install::Software/Mq_install::Software::Unix[mq_installation_9.2.0.0]/Exec[Accept MQ License Requirements]/returns: executed successfully
Notice: /Stage[main]/Mq_install::Software/Mq_install::Software::Unix[mq_installation_9.2.0.0]/Package[MQSeriesRuntime-9.2.0-0]/ensure: created
Notice: /Stage[main]/Mq_install::Software/Mq_install::Software::Unix[mq_installation_9.2.0.0]/Package[MQSeriesGSKit-9.2.0-0]/ensure: created
Notice: /Stage[main]/Mq_install::Software/Mq_install::Software::Unix[mq_installation_9.2.0.0]/Package[MQSeriesJRE-9.2.0-0]/ensure: created
Notice: /Stage[main]/Mq_install::Software/Mq_install::Software::Unix[mq_installation_9.2.0.0]/Package[MQSeriesJava-9.2.0-0]/ensure: created
Notice: /Stage[main]/Mq_install::Software/Mq_install::Software::Unix[mq_installation_9.2.0.0]/Package[MQSeriesServer-9.2.0-0]/ensure: created
Notice: /Stage[main]/Mq_install::Software/Mq_install::Software::Unix[mq_installation_9.2.0.0]/File[Remove temporary files]/ensure: removed
Notice: /Stage[main]/Ibm_profile::Mq_machine::Manager_setup/Mq_manager[QM01]/status: status changed 'Ended normally' to 'Running'
Notice: /Stage[main]/Ibm_profile::Mq_machine::Autostart/Mq_install::Autostart[QM01]/Exec[stop QM01 running outside systemd]/returns: executed successfully
Notice: /Stage[main]/Ibm_profile::Mq_machine::Autostart/Mq_install::Autostart[QM01]/Service[mq@QM01]/ensure: ensure changed 'stopped' to 'running'
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;when-to-update&quot;&gt;When to update&lt;/h2&gt;

&lt;p&gt;Before you can apply a fixpack or even install a new major version of MQ, you are required to shut down the running MQ software on your system. Obviously, you want control over when you do this. You don’t want Puppet® to shut down your MQ messaging during operating hours. One of the ways to get control over this is to specify a time frame for you &lt;code class=&quot;highlighter-rouge&quot;&gt;service_window&lt;/code&gt; parameter. Let’s say you are allowed to shut down your MQ software every night between 1:00 and 2:00. You can tell Puppet® this by setting the &lt;code class=&quot;highlighter-rouge&quot;&gt;service_window&lt;/code&gt;.&lt;/p&gt;

&lt;div class=&quot;language-yaml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;s&quot;&gt;mq_install::fixpack::service_window&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;    &lt;span class=&quot;s&quot;&gt;1 - 2&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;mq_install::software::service_window&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;   &lt;span class=&quot;s&quot;&gt;1 - 2&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;This means that Puppet® will skip the shutdown and installation of a new fixpack or major version every time &lt;strong&gt;unless&lt;/strong&gt; it is currently running in the service window.&lt;/p&gt;

&lt;h2 id=&quot;how-about-an-initial-install-outside-the-service-window&quot;&gt;How about an initial install outside the service window&lt;/h2&gt;

&lt;p&gt;When you are installing a brand new system, you probably don’t need to adhere to the service window because no users are using the system yet. The MQ modules will detect this use-case and install any requested fixpack on initial install&lt;/p&gt;

&lt;h2 id=&quot;we-need-more-control&quot;&gt;We need more control&lt;/h2&gt;

&lt;p&gt;Although the service window gives you a lot more control, for some organizations, it is not enough.  Maybe you need to contact your business and use a precise moment for a subset of systems. For this use case, we can use the Puppet® plan (or Bolt plan). In this blog post, we will show you the bolt commands.&lt;/p&gt;

&lt;p&gt;To tell the Puppet® agent to leave the MQ versions like they are, we need to specify the next hiera data:&lt;/p&gt;

&lt;div class=&quot;language-yaml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;s&quot;&gt;mq_install::fixpack::service_window&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;    &lt;span class=&quot;s&quot;&gt;INSTALL_ONLY&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;mq_install::software::service_window&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;   &lt;span class=&quot;s&quot;&gt;INSTALL_ONLY&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;This means that &lt;strong&gt;only&lt;/strong&gt; on a first Puppet® run, Puppet® will install the software and the fixpack, but Puppet® will &lt;strong&gt;never&lt;/strong&gt; do an update. To actually do the update, we need to run a bolt plan.&lt;/p&gt;

&lt;h2 id=&quot;puppetbolt-plans&quot;&gt;Puppet/Bolt plans&lt;/h2&gt;

&lt;p&gt;Here is the command that shows the available bolt plans.&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ bolt plan show --modulepath /etc/puppetlabs/code/environments/production/modules/ | grep mq_install
  mq_install::apply_fixpack           Apply the in hiera specified MQ fixpack to the specified nodes.
  mq_install::apply_upgrades          Apply the in hiera specified MQ upgrades to the specified nodes.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Let’s see some more information about the plan &lt;code class=&quot;highlighter-rouge&quot;&gt;mq_install::apply_fixpack  &lt;/code&gt;.&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;bolt plan show --modulepath /etc/puppetlabs/code/environments/production/modules/ mq_install::apply_fixpack
mq_install::apply_fixpack
  Apply the in hiera specified MQ fixpack to the specified nodes.

Usage
  bolt plan run mq_install::apply_fixpack targets=&amp;lt;value&amp;gt;

Parameters
  targets  TargetSpec
    The MQ node(s) you want to apply a software update to

Module
  /etc/puppetlabs/code/environments/production/modules/mq_install
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;As you can see, the bolt plan takes a parameter called targets. You can pass a comma-separated list of target names, wildcard patterns, or group names to a plan parameter of type TargetSpec. For more information on the TargetSpec type, see &lt;a href=&quot;https://puppet.com/docs/bolt/latest/writing_plans.html#targetspec&quot;&gt;Writing plans in the Puppet® language&lt;/a&gt;. The fact that you can specify specific target nodes means that you can precisely select the nodes you want to update the MQ fixpack with a bolt plan. The plan is executed directly and concurrently on all specified target nodes.&lt;/p&gt;

&lt;p&gt;Here is an example of this running on a node.&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ bolt plan run --modulepath /etc/puppetlabs/code/environments/production/modules/ --hiera_config /etc/puppetlabs/code/environments/production/hiera.yaml mq_install::apply_fixpack  targets=mq01.example.com
Starting: plan mq_install::apply_fixpack
Starting: Uploading Enterprise Modules run-time information... on mq01.example.com
Finished: Uploading Enterprise Modules run-time information... with 0 failures in 0.04 sec
Starting: install puppet and gather facts on mq01.example.com
Finished: install puppet and gather facts with 0 failures in 5.88 sec
Starting: apply catalog on mq01.example.com
Finished: apply catalog with 0 failures in 53.43 sec
Puppet: When a fixpack update is detected, it will take place directly without any schedule
Puppet: When a software update is detected, it will be skipped, because service window is set to INSTALL_ONLY
/Stage[main]/Mq_install::Fixpack/File[/tmp/mq_fixpack_9.1.0.8]/ensure: created
/Stage[main]/Mq_install::Fixpack/Archive[/tmp/9.1.0-IBM-MQ-LinuxX64-FP0008.tar.gz]/ensure: download archive from /vagrant/modules/software/files/9.1.0-IBM-MQ-LinuxX64-FP0008.tar.gz to /tmp/9.1.0-IBM-MQ-LinuxX64-FP0008.tar.gz and extracted in /tmp/mq_fixpack_9.1.0.8 with cleanup
/Stage[main]/Mq_install::Internal::Mq_stop/Exec[Stop MQ manager QM01]/returns: executed successfully
/Stage[main]/Mq_install::Fixpack/Mq_install::Internal::Mq_packages[U9108-9.1.0-8]/Package[MQSeriesRuntime-U9108-9.1.0-8]/ensure: created
/Stage[main]/Mq_install::Fixpack/Mq_install::Internal::Mq_packages[U9108-9.1.0-8]/Package[MQSeriesJRE-U9108-9.1.0-8]/ensure: created
/Stage[main]/Mq_install::Fixpack/Mq_install::Internal::Mq_packages[U9108-9.1.0-8]/Package[MQSeriesJava-U9108-9.1.0-8]/ensure: created
/Stage[main]/Mq_install::Fixpack/Mq_install::Internal::Mq_packages[U9108-9.1.0-8]/Package[MQSeriesServer-U9108-9.1.0-8]/ensure: created
/Stage[main]/Mq_install::Fixpack/Exec[Remove temporary files for fixpack 9.1.0.8]/returns: executed successfully
/Stage[main]/Main/Mq_install::Autostart[QM01]/Service[mq@QM01]/ensure: ensure changed 'stopped' to 'running'
Puppet: Applied catalog in 41.75 seconds
Finished: plan mq_install::apply_fixpack in 1 min, 1 sec
Plan completed successfully with no result
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;experience-the-power-of-puppet-for-ibm-mq&quot;&gt;Experience the Power of Puppet® for IBM MQ&lt;/h2&gt;

&lt;p&gt;If you want to play and experiment with Puppet® and IBM MQ, please contact us to discuss your specific use case and requirements. We can help you get started with our modules and provide guidance on implementation.&lt;/p&gt;

&lt;p&gt;For more information about our IBM MQ solutions, please &lt;a href=&quot;/company/contact/&quot;&gt;contact us&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;In this blog post, we have shown you easy it is to (re)gain control of the MQ fixpacks and versions you are running on your fleet of systems. Puppet, in combination with the Puppet® modules for MQ make it very easy to automate this work. The Puppet® desired state language can work seamlessly with Puppet(Bolt) plans to give you full control over the timing of your updates. Because the modules support multiple operating systems, your entire MQ fleet can be managed with one single approach and set of tools.&lt;/p&gt;

&lt;p&gt;If you would like to know more, contact us at &lt;a href=&quot;mailto:info@enterprisemodules.com&quot;&gt;info@enterprisemodules.com&lt;/a&gt; or by phone: +31 (0)653 847 326&lt;/p&gt;

&lt;h2 id=&quot;about-us&quot;&gt;About us&lt;/h2&gt;

&lt;p&gt;Enterprise modules is the leading developer of enterprise-ready Puppet® modules for Oracle databases,Oracle WebLogic, and IBM MQ 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.&lt;/p&gt;

</description><pubDate>Wed, 25 Aug 2021 00:00:00 +0200</pubDate><link>https://www.enterprisemodules.com/blog/2021/08/mq-version-control/</link><guid isPermaLink="true">https://www.enterprisemodules.com/blog/2021/08/mq-version-control/</guid><category>puppet</category><category>MQ</category><category>blog</category><category>puppet</category><category>mq</category></item></channel></rss>