Debunking Three Myths of Puppet Code
Tags: puppet, devops
Published: 2021-07-19 22:45:48

I see a lot of articles that sing the praises of Puppet, rightfully so, but I keep noticing authors detailing "Cons" of the product that simply aren't true.  I want to dispel a few myths that seem to circle around Puppet, sticking doggedly, despite being absolutely inaccurate.  Allow me to shed a little light and reveal the truth.

**Myth #1: "You need to know Ruby to use Puppet"**

You do not need to know Ruby.  You do not have to write a single line of Ruby code to create Puppet catalogues, manage nodes, run Tasks and Plans, etc.  None.  Puppet has a robust Domain Specific Language (DSL) that you use to define all the resources you want to manage, declaratively.  While Puppet is still extendable via Ruby, the requirement to code using Ruby is a thing of the past.  You don't even need to be a programmer to use the Puppet DSL; it's simple and intuitive, which brings us to the next myth.

**Myth #2 "Puppet is hard to learn/use"**

I honestly don't know how this got started.  It's like the apocryphal "You're never more than three feet from a spider"; someone said it and it just echoes endlessly.  I assume this myth is a legacy of myth #1, but I'm not sure.  What I do know is that it's entirely false.

Puppet's DSL is a declarative language that can be read and understood by anyone.  The syntax is straightforward and only defines the desired state.  Puppet knows how to achieve the desired state in supported environments.  You do not need to write imperative instructions.  Here is a working example of Puppet code that will install and maintain the Nano editor:

  ```package { ‘nano’:
    ensure => installed,
  }```

That's all there is to it.  And that will work on any operating system where nano is supported (and the package is named 'nano'.)  Puppet's DSL is self-documenting.  Anyone should be able to read the class and understand how the resource is being managed.  This example ensures the package nano is installed.  

You can write more complex classes with dependencies on operating system, resource states and even metadata Puppet collects from the managed node, but all classes use the same simple, self-documenting declarative code.  Additional working examples are [here](https://github.com/Jlaffey-Puppet/cs_control-repo).  You can manage an estate of 100,000 machines without a line of Ruby code to be found.  Speaking of managing nodes at scale, let's talk about 

**Myth #3 "Puppet code base can be unwieldy and difficult to maintain"**

Okay, if you don't organize properly, your garage, your books, and your mint-condition Pokemon trading cards can get unwieldy and difficult to maintain.  One of Puppet's key differentiators is the ability to scale to 100's of thousands of nodes.  Many Puppet users do this, and they keep their Puppet code well organized, no Marie Kondo art of organizing required.    

Puppet uses a method called [Roles and Profiles](https://puppet.com/docs/pe/2019.8/osp/the_roles_and_profiles_method.html) to reliably build reusable, configurable, and refactorable system configurations saved as Infrastructure as Code (IaC).  Profiles are wrapper classes that use multiple components (classes and other profiles) to configure a layer technology stack.  At the simplest layer a profile could be a class that ensures Java is installed at a specific version, and include case statements or Hiera variable to customize the package name (e.g. 'apache' for linux systems and 'win_apache' for Windows).  A more complex profile can layer several related packages or settings together, for example: ensure Tomcat is installed, the correct ports and home paths are set, and the service is started.

Profiles allow Puppet users to maintain related configuration in a discrete IaC block, stored in a repository.  Profiles can then be combined modularly to construct a full system configuration (a Role.)  Refactoring becomes simple as changes are made in one profile and will roll out to all instances assigned that profile.  Roles and Profiles provide an organized method of constructing and maintaining complex configuration at a scale that monolithic playbooks cannot support.  

Conflict resolution is handled gracefully.  Discretion being the better part of valor, if a conflict arises in the management of a resource Puppet will valiantly refuse to compile the catalog until the conflict is removed.  If at first glance this seems difficult, in reality it lets users understand what is being managed by the team at large.

These outdated and inaccurate beliefs about Puppet keep getting repeated as “go-to” disadvantages of using Puppet.  While it’s flattering to see how hard it is to come up with new items for the ‘cons’ list, I’d like to see these put out to pasture.