Ask Your Question

How to build a proper Hiera hierarchy?

asked 2013-09-19 01:16:30 -0600

LindaLoo gravatar image

The Hiera docs have a number of very simple hierarchy examples.

My system is more complex than just common, $::somefact, $::fqdn.

Does anyone have a reasonably complex hierarchy they'd like to share and the rationalization they used to arrive at it?

I have concerns about starting with a hierarchy that won't be flexible enough in the near future.

edit retag flag offensive close merge delete

2 Answers

Sort by ยป oldest newest most voted

answered 2013-09-20 09:10:50 -0600

ramindk gravatar image

updated 2014-10-21 16:15:03 -0600

Picking a Hiera hierarchy is harder than it appears. Ultimately we're trying to create a data model within the confines of Hiera that accurately represent your system. Ideally it will cover the current system and be flexible as your system grows or changes in the future.

The primary driver for your hierachy is going to be the way your system is currently organized. You probably have a few environments, many roles, and perhaps different sites. Each of these probably affect settings so they should be represented. A secondary concern in my opinion is how your modules written. Overall I lean towards pushing system data into Hiera and settings defaults in my modules in a params class. However as parametrized classes have matured moving what has normally been internal module data in a ::params class into Hiera might work better for you.

Assuming you want to handle both internal module data and system data your hierarchy might look like this.


    - "fqdn/%{clientcert}"
    - "env/%{environment}/%{role}/%{location}"
    - "env/%{environment}/%{role}"
    - "locs/%{location}"
    - "roles/%{role}"
    - "env/%{environment}"
    - "ops/%{operatingsystem}"
    - "os/%{osfamily}
    - common

I recommend using directories to provide simple namespaces for your hierarchy. Nothing worse than a $::role conflicting with an $::environment and matching where you weren't expecting.

Most people choose common or default at the bottom of the hierarchy and $::fqdn or $::clientcert as the top. This make conceptual sense and provides a simple method to have the last word on setting a value. I choose to put $::osfamily which can match many OS beneath $::operatingsystem which is the more specific case.

We wrote two custom facts $::location and $::role to help classify our machines. $location is as simple as checking IP address or subdomain. Our naming scheme is fairly sane so $::role is just parsing the hostname. If you don't have multiple sites no need for location. If you have multiple business units in a singe location you many want to add an additional fact into your hierarchy. These facts could be more complex and query services like an internal Opsdb or AWS EC2 metadata.

Setting $::environment, $::role, and $::location is that order is personal preference. You could easily have done $::environment, $::location, and $::role.

Some people have built hierarchies using $::calling_class or $::calling_module, but I find that too specific and the more general $::role works better.

Using the Varnish proxy server as an example we might set different amounts of RAM to use based on size of machines of role. Frontend servers just need a small cache for application acceleration. The Cache servers will need a larger storage size because their primary function is to cache.


varnish::admin:          'yes'
varnish::sess:           '16384'
varnish::storage_size:   '128MB'
varnish::threadmin:      '10'


varnish::storage_size:  '512MB'


varnish::storage_size:  '4GB'


varnish::storage_size:  '2GB'

In this example fe01.stage would get the value from common.yaml of 128MB for the storage size.

edit flag offensive delete link more


wow, this is really good example. thanks ramindk

3h4x gravatar image3h4x ( 2014-12-16 02:10:57 -0600 )edit

answered 2013-09-19 05:11:55 -0600

deric gravatar image

It depends on your use case, you could use custom variables e.g. for geographical location of your servers or just for different cluster. Using production and development environment settings also could be useful.

  - "node/%{::fqdn}"
  - "%{::environment}"
  - "virtual/%{::virtual}"
  - "osfamily/%{osfamily}"
  - "%{operatingsystem}"
  - common
edit flag offensive delete link more

Your Answer

Please start posting anonymously - your entry will be published after you log in or create a new account.

Add Answer

Question Tools



Asked: 2013-09-19 01:16:30 -0600

Seen: 5,149 times

Last updated: Oct 21 '14