A hieradata style guide

Hiera, OCD Engineers, and You.

Why am I writing this?

Good question. I’ve not seen a post on the topic, and I had to write something up for work, so I figured everyone’s entitled to my opinion. I wrote something similar to this to show engineers who submit a pull request or a topic branch to be merged that didn’t pass our hieradata standards for one reason or another, so the tone is somewhat lighthearted. We just gave the engineer a paper cut. The last thing we want to do is pour lemon juice on it. Nevertheless, we’re concerned about keeping this data organized, neat, and well groomed.

I know, it seems a little pedantic, right? The problem is that if we don’t maintain these standards as a team, the burden of backlog maintenance inevitably falls to the person whose OCD kicks in first and they just can’t take the chaos anymore. Things must be brought back into homeostasis and order so that maybe the demons will stop snarling… and blissful sleep will once again come.

In all seriousness, this page’s purpose in life is to outline how I think hieradata should be maintained so that people can share a sandbox nicely.

What should be in hiera and how should it be collected?

Well, everything, but the devil’s always in the details. In our recent refactor, we’re taking the chance to codify some of the ways we want to interact with hiera to make things more uniform. Here’s what that means:

  • Component modules should fall back to their own built-in data for the most part.

    Translation: Do not put component modules’ parameters in hiera for automatic data binding, ie: ruby::version. use the profile::ruby::1.9.3 class to bring that version in, and add parameters in hiera for that profile instead.

  • Profile classes should be used to provide the glue between hieradata and component modules.

    If you’re adding a hiera call to a component module, your pull request will likely not be accepted. If you need a specific parameter to automatically have a different value, and there’s not already a profile module which suits your needs, create a new profile and feed the component module your special parameter value there.
    This paradigm has many benefits. It really helps draw a clear line between ‘component’ modules and ‘profiles’. Allowing business logic to creep into component modules hinders us by preventing that module from being re-used by other teams, or other companies. None of us want to re-invent the wheel, and we all have better things to do anyways. Following this paradigm will reduce the number of very similar tools you’re using to perform slightly different functions, and overall simplify and streamline your puppet development process.

  • Profile classes should have parameters, and the default values of those parameters should be an explicit hiera call for the variables fully qualified namespace

    ala:

    class profile::example(
    $myparam = hiera(‘profile::example::myparam’)
    ){

    }

    This way, if we forget to add in the appropriate data in hiera, we fast fail. it also solidifies where we inject hieradata into our modulebase so that we have a consistent means of comprehending where data is being derived from.

The little things matter

  • Naming things are hard.

     

  • Hieradata keys which are meant to be queried by multiple modules should be named with a consistent prefix within hieradata

    There’s lots of data that can be stored in hiera. The Hiera Documentation does a pretty good job of explaining what you can put in there. But we’re really talking about how to organize the chaos here.

    We chose to prefix common module keydata with ext_. Pick whatever you want, but be consistent, and use an easily grokable name for your key. Someone is going to be looking at this at 3am wondering why it isn’t working. Think about them, and try to name things briefly, but succinctly.

  • Keys should be separated by a consistent delineator token

    It can be confusing to tell when one module’s hieradata needs end, and anothers’ begins. Give yourself, and everyone else a clue about what keys are changing what bits. We dictated that every module/profile’s hieradata should be separated by a single line consisting of 80 hash characters.

    ################################################################################

You don’t have to use our standard, but use one. it makes merges easier, and gives clear context.

  • YAML is sensitive.

    A superfluous preceeding space to a key will result in a failed result for that key. make sure you run your yaml file through some syntax validation before trying to merge your changes. (Unless, of course, Dos Equis is you beverage of choice)

  • Align your key values

    Ok, so I don’t know about you, but this grates on my eyes:

    ################################################################################
    skinnyjeans : awesome
    dayglo: instyle
    foo:bar
    disco :bestmusicever
    bacon:crispy
    ################################################################################

    true, the content is upsetting, but the alignment of the data makes it hard to read.

    ################################################################################
    bacon:   'perfectly chewy but slightly crispy'
    data:    'grokable'
    fashion: 'sensible'
    people:  'happy'
    ################################################################################

    Doesn’t this look better? align the assignment separator and your data will be easier to assimilate at 0300 by our aforementioned engineer, (man, he’s really having a hard time of it, isn’t he?)

To quote or not to quote

You should quote your data. Period. it provides encapsulation, and provides some extra context. Also, I like quotes. I think they’re pretty.

  • Singlequotes are for strings

    Using doublequotes tells hiera to inspect the value contained within the quotes for variables to interpolate. this requires extra time. No, not a lot of extra time, but still. it’s not hard to use single quotes instead of double quotes for simple strings.

  • Doublequotes are for interpolation

    use a doublequote anyplace where you want hiera to do another hiera call to look up data. This is documented a bit here

  • Fancy quotes are evil

    They break all sorts of things. beware of rich text editors and hiera!

Ordering Matters

  • The hieradatafile must be kept alphabetically organized by keyname.

    Period. Failure to comply with this will make you crazy over time. The underlying reason for this is that hiera will act in unexpected ways if you have a key listed twice. Which one will it deliver to a node? Again, think of the person trying to debug this at 0300. If everything is alphabetically organized,

    • There wouldn’t be duplicate keys in the first place
    • It would be easy to spot

    The amount of time it takes now to alphabetize your keys is trivial to the time spent in a critical situation when things aren’t working because of a hard to find problem. Is the horse dead yet? Good. OK moving on.

The Unattended Garden – Having a standard means following it.

There’s a bizarre phenomenon wherein once sufficient entropy/chaos exists in a dataset, even the most attentive and diligent engineers are prone to tossing their hands in the air, sighing heavily, and forgetting the standards existed in the first place. Don’t get to that point. It is much harder to UNLEARN bad habits than to maintain good ones. Try to keep your hiera garden nice and well tended. Pull weeds as you see them spring up. you’ll be happier, and have more hair because of the extra energy you spent.

Leave a Reply