Configuring puppetdb module in Puppet using Hiera

hierapuppetpuppetdb

I'm trying to install the PuppetDB Module. Part of this bundles a module for installing some requisite Postgres instances which I am using as well.

We primary use heira to configure roles and set various properties.

I have the configuration far enough long that if I add

roles:
    - role::postgresql_puppetdb

To a hostnames hiera yaml file it will get picked up and get a basic postgres instance pushed out.

I'm stuck on getting specific postgresql.conf variables set. For example I've tried

roles:
   - role::postgresql_puppetdb
      - wal_level: hot_standby

However that does get pushed to on subsequent agent run.

I'm hoping someone out there might have gone through trying to model PuppetDB configs in this manner and point out what I'm doing wrong.

Best Answer

For Puppet to lookup class parameters in Hiera (which it does by default since 3.0.0) these parameters need to be specified as simple key-value pairs, not complex datatypes.

This is how you would specify the datadir parameter of the class postgresql::server in the puppetlabs-postgresql module to point to an alternate data directory for Postgres:

# /etc/puppet/hieradata/foo.example.com.yaml
---
# Puppet automatically looks here for parameters when applying the class postgresql::server
postgresql::server::datadir: /srv/postgres/main

However, I don't think this is what you need in your case. You want to specify Postgres configuration parameters, for which you need to use the postgresql::server::config_entry defined type. There is currently no way to lookup type parameters in Hiera, that only works for class parameters.

So either you parameterize your role::postgresql_puppetdb class so you can pass class parameters to it, that in turn get fed into postgresql::server::config_entry declarations, or you use the create_resources() function together with hiera_array() or hiera_hash() to look up the Postgres configuration settings you want to apply.

An example for the first approach:

class role::postgresql_puppetdb (
  wal_level => 'minimal'
  ...
) {

  class { 'postgresql':
     ...
  }

  class { 'puppetdb':
     ...
  }

  postgresql::server::config_entry { 'wal_level':
    value => $role::postgresql_puppetdb::wal_level
  }
}

And then in Hiera.

# /etc/puppet/hieradata/foo.example.com.yaml
---
role::postgresql_puppetdb::wal_level: hot_standby

This is obviously a bit inflexible as you need to expose every tunable parameter and configuration setting the postgresql class provides through your role::postgresql_puppetdb class as well. Of course this might be enough for you if you know you only need to expose few tunables like this.

An example for the second approach:

class role::postgresql_puppetdb {

  class { 'postgresql':
     ...
  }

  class { 'puppetdb':
     ...
  }

  $postgres_config_entries = hiera_hash('postgres_configs', {})

  create_resources('postgresql::server::config_entry', $postgres_config_entries)

}

Then in Hiera:

# /etc/puppet/hieradata/foo.example.com.yaml
---
postgres_configs:
  wal_level:
    value: hot_standby
  authentication_timeout:
    value: 120s
  krb_server_keyfile:
    value: /var/lib/postgresql/postgresql.keytab

And so on. This is more flexible and allows you to set arbitrary Postgres parameters on every hierarchy level you want. In this case, of course, Hiera will only be consulted for these configuration settings when the role::postgresql_puppetdb class is included, but nothing keeps you from putting that hiera_hash-create_resources combo in other roles, possibly a role::postgresql.

I hope this was understandable and coherent enough to follow. The above is of course untested like posted, but we use this very strategy (create_resources, hiera_hash) to manage local and system accounts, repos, sudoers rules, Tomcat instances and others. Will revisit the question tomorrow when I am less tired.

But do have a look at this excellent question on Puppet-Ask: https://ask.puppetlabs.com/question/1655/an-end-to-end-roleprofile-example-using-hiera/

It walks through a similar setup based on HAproxy. Very useful to understand.