Published on 27 February 2014 by

Does the term “best practices” make your skin crawl? It makes Gary Larizza’s skin crawl, too. As he says, “one person’s best practice is another person’s ‘What the **** did you just do?’” (Yeah, that’s edited because this is a family newspaper — er, blog.)

Nonetheless, Gary, a professional services engineer here at Puppet Labs, offers some best practices for building Puppet modules on his blog. Here’s a quick summary of his recent three-parter, which is a great introduction to Gary’s blog, if you haven’t already added it to your regular Puppet reading. Gary’s penchant for couching helpful advice in an amusingly self-deprecating style makes his blog as fun as it is useful.

Learn More

Share via:
Posted in:

Been having on going discussions about puppet modules across multiple blogs. One thing that concerns me with the future of puppet is that a lot of the module developer enthusiasts look at modules as code, so there is a lot of effort in making the code look beautiful to a developer but in doing so, seems to lose focus on the simplicity of code (even if chunky) that is easily readable and describable to non developers - you know, the sysadmins and operations folks who know enough ruby to get in trouble but can easily read a simple DSL. Is there anyone else running into this? has it been an issue? I've seen some blogs go as far to say that to be successful everyone should learn Ruby first... nice on paper, but practical in enterprise? I'd also like to see more emphasis on the back side of a DSL, modules allow us to define a system, but only resources allow us to derive a system - can we work on bringing these two together?

@byron - One of the byproducts of Roles and Profiles is that your top-level wrapper classes (i.e. Roles) give you the most legible code (lots of "include profile::tomcat" and the like). For someone new to Puppet, Roles give you visibility without having to descend into resources - so you feel like you understand what Puppet's GOING to do without needing to see the internals. Need to know a bit more? Open up the profile. In the profile, you see a bit more - class declarations, hiera calls, etc.. Need to know more? Open up a component module and you see the resources. There's now a series of layers that allow you to get more and more...technical with what Puppet is doing.

As for code that's legible, I'd argue that the DSL is pretty legible even to people who don't identify as 'programmers'. It's a configuration language, versus a programming language, so you see WHAT you want in the end without having to understand HOW Puppet is going about get there (i.e. seeing a package will be installed without having to know that `yum install httpd -y` is getting invoked).

As with everything, though, the code is only as legible as the person who's writing it, and you CAN write some pretty complicated DSL code that tries to pull in bits of Ruby (with things like inline_template() for example). I recommend that people err on the side of legibility instead of trying to condense the work their doing into "as few lines as possible"

Understand, though, that you DON'T need to know Ruby to be effective with Puppet. Seriously. I worked with Puppet for over a year very successfully before I realized how to write Ruby plugins to Puppet (and before I had the need for a plugin). This is why the DSL exists - to give you properties that can accept values without having to write methods to make changes.

To your last comment, I believe that's the goal of the Puppet ecosystem - modules can be treated like 'libraries', where you pass data to them and don't necessarily care/worry about exactly WHAT they're doing underneath the hood so long as the end-state you want is achieved, right? After using Puppet for 5 years, I feel we're definitely getting to that place. The consulting that I'm doing with customers is more around data being passed to modules we pull from the Forge, versus having to hand-roll modules ourselves (so, in this way, we're being more concerned with modules than individual resources).

Did this address what you were asking?

@Gary - Good stuff & thanks for replying.

Roles & Profiles are great, but I already abstracted those out with Groups in the theforeman and Smart Variables. When i had my last discussion with Puppetlabs peeps during advanced puppet training the roles & profiles was sort of a step back from hiera ideals since the roles and profiles weren't described through yaml but more manifests. I do like the idea though and thrilled to see it grow and flourish.

I agree that basic DSL is legible, very legible and very descriptive and it should always strive to be so, i see DSL less as a tool simply to automate something but more as a tool to describe and document the process. My end goal isn't necessarily automation itself as to me, automation is a symptom of consistency (and automation can have many methods be it robots/tools/procedures/frameworks/models/abstracts). It may just be my perspective, but i do seem to see more work in making DSL more developer centric instead of "simple" (being subjective..). It really peaked my interest in this debate as people try and do hiera in modules to separate code and data - but in doing so they're just (to me) taking a very simple (albeit chunky) if then else style approach to defining a state/process and turning it into an elegant (programmatically) solution of hiera looks functions, module includes and external yaml files for resource definition - something that is hard to look at and see a state from without actually debugging and interpreting the code or nooping it over and over. (now the code isn't a definition, but another process) After using somthing like powershell with get/set methods and very abundant and deep resource types and using similar (limited) resource types in puppet and seeing the elegance of pulling a config as well as applying a config - it seems all this work on making modules more robust, more programmatic and more developer friendly is actually a huge effort in a superficial direction. The more i think about it the more i see modules should be less modules to apply logic and more modules as resource types. So instead of creating a mysql module to create a mysql installation one could simply instantiate a mysql resource and define the configuration or if you're already running mysql you could then export the configuration as a resource. If you need to customize the resource, you could extend/customize the resource definition instead of forking the module (custom paths, os specific features.. what have you) - that way instead of data being in the module, data being in the roles and profiles and data being in an ENC or external lookup (puppetdb/hiera/custom enc..) puppet can derive, compare and apply states through resources/methods. It just seems that a lot of modules and a lot of module styles are only worked towards implied state, when a big part of the "Desired" state is also being able to derive something, test something, validate something & compare something.

In many ways think the "what they're doing underneath the hood" is quite possibly the most important piece of the desired state since that "what they're doing" is the documentation and the interface of the state itself. Make sense?

Gary;

Great article. I love the inclusion of the f-bombs. In any case could you provide a layout (or link to one) showing explicitly how these components (specifically classes/roles) would be laid out?

The content of this field is kept private and will not be shown publicly.

Restricted HTML

  • Allowed HTML tags: <a href hreflang> <em> <strong> <cite> <blockquote cite> <code> <ul type> <ol start type> <li> <dl> <dt> <dd> <h2 id> <h3 id> <h4 id> <h5 id> <h6 id>
  • Lines and paragraphs break automatically.
  • Web page addresses and email addresses turn into links automatically.