Using a module that is not 100% hiera-compliant

139 views
Skip to first unread message

Ugo Bellavance

unread,
Oct 18, 2016, 1:56:59 PM10/18/16
to Puppet Users
Hi,

I am using camptocamp/postfix for my postfix configuration.  I originally defined all my configs manifests but now I would like to change to using hiera.  Unfortunately, this module doesn't support hiera for some of the configs, so I must define many parameters in the manifests.  I wanted to use hiera for simplicity, but also because I have a very nice use case:  I have one SMTP front-end with its own specific configs (anti-spam/virus), and a series of regular hosts. Traditionally, all hosts that are in the same subnet as the Exchange server would use it as relayhost and all the other hosts use the smtp front-ends.  Therefore, here's what I did:

hiera.yaml:

---
:backends:
#  - regex
  - yaml
:yaml:
  :datadir: /etc/puppet/hiera
#:regex:
#  :datadir: /var/lib/hiera
:hierarchy:
  - "host/%{fqdn}"
  - "domain/%{domain}"
  - "env/%{::environment}"
  - "os/%{operatingsystem}"
  - "osfamily/%{osfamily}"
  - "networks/%{network_ens192}"
  - "virtual/%{::virtual}"
  - common

This way, I define the exchange server as relayhost for the exchange network in /etc/puppet/hiera/networks/192.168.155.0.yaml, and set the smtp frontend as relayhost in /etc/puppet/hiera/common.yaml.

However, since I can't put all the settings in hiera, I must put some in the class declaration for the smtp frontends.  When I declare the postfix class in both my default profile and in the smtp frontend profile, I get an error saying that the class cannot be declared twice (Class[Postfix] is already declared; cannot redeclare at /etc/puppet/manifests/nodes/smtp_postfix_servers.pp:19)

Another solution would be to declare the profile in all my roles, but it's far from perfect.

Is there a simple solution?

I guess that I could do an if based on ipaddress in my default profile, but I wanted to use hiera as much as possible. Yes I created an issue to ask for full hiera support.

Thanks,

Ugo

Rich Burroughs

unread,
Oct 18, 2016, 2:41:38 PM10/18/16
to puppet...@googlegroups.com
On Tue, Oct 18, 2016 at 10:56 AM, Ugo Bellavance <ug...@lubik.ca> wrote:
However, since I can't put all the settings in hiera, I must put some in the class declaration for the smtp frontends.  When I declare the postfix class in both my default profile and in the smtp frontend profile, I get an error saying that the class cannot be declared twice (Class[Postfix] is already declared; cannot redeclare at /etc/puppet/manifests/nodes/smtp_postfix_servers.pp:19)

Another solution would be to declare the profile in all my roles, but it's far from perfect.

Is there a simple solution?

I guess that I could do an if based on ipaddress in my default profile, but I wanted to use hiera as much as possible. Yes I created an issue to ask for full hiera support.

I don't really know of a better solution than the ones you mentioned. Perhaps someone else will. But yeah if you need to apply that class to the node with a different value for that param, it can't also get applied from your default profile.

Having to add it to all of the roles is a bit of a pain too. I've been there. Then the concern is someone leaving it out accidentally.

I like the suggesting of the conditional in the default profile best. It's maybe not as clean as Hiera but it's less messy than the alternatives I think, and it should be very visible there.


Rich

Angel L. Mateo

unread,
Oct 19, 2016, 3:10:01 AM10/19/16
to puppet...@googlegroups.com
El 18/10/16 a las 19:56, Ugo Bellavance escribió:

> However, since I can't put all the settings in hiera, I must put some in
> the class declaration for the smtp frontends. When I declare the

What option can't you put in hiera? I'm using this same module and all
of my config is in hiera. And with puppet automatic parameter lookup I
don't find any reason why a module couldn't be hiera compatible.

--
Angel L. Mateo Martínez
Sección de Telemática
Área de Tecnologías de la Información
y las Comunicaciones Aplicadas (ATICA)
http://www.um.es/atica
Tfo: 868889150
Fax: 868888337

Luke Bigum

unread,
Oct 19, 2016, 4:42:49 AM10/19/16
to Puppet Users
Hello,

You are describing a problem we run into every now and then. Your default profile is what we call "mandatory" here, and then you have an edge case where 99% of your servers have Postfix the same way, and a couple have it a different way. Unfortunately that 99% means Postfix is not mandatory and so can't live in your default profile.

If you use smart class inheritance to structure your roles you should be able to remove most of the places you need to include postfix. Something like this:

class role::base {
  include profile::mandatory
  include profile::somethingelse
  include postifx
}

class role::anotherserver inherits role::base {
  include profile::anotherprofile
}

class role::postfixrelay {
  include profile::mandatory
  include profile::postfixrelay
}



Or another way would be move the majority of your postfix business logic out of Hiera (which as you describe is not working for you) and handle it in a profile. The below code introduces a simple Enum on your profile to control what "type" of postfix you want:

class profile::mail(
  $type = 'normal',
) {
  if ($type == 'normal') {
    class { 'postfix':
        ... normal stuff ...
     }
  }
  elsif ($type == 'relay') {
    class { 'postfix':
        ... relay stuff ...
  } else {
    fail("Type '$type' is not supported")
  }
}

$ cat /etc/puppet/hiera/networks/192.168.155.0.yaml
...
profile::mail::type: 'relay'



I personally would prefer the second option. It enforces the same postfix config on almost all your servers (looking at your Hiera hierarchy there are plenty of levels to make your servers' Postfix "different" from each other). It's also easy to test with rspec.


-Luke

Chadwick Banning

unread,
Oct 19, 2016, 8:01:34 AM10/19/16
to Puppet Users
I looked at the PR (https://github.com/camptocamp/puppet-postfix/pull/50) to add "Hiera support" and it appears that it just add some parameters that take hashes that are used to auto-generate instances of defined types. I wouldn't call this "Hiera support", I'd just call it "convenience parameters".

There's no reason you couldn't just do this on your own in a profile (or anywhere else):

$configs = hiera('<key_name>')
create_resources('postfix::config', $configs)

Ugo Bellavance

unread,
Oct 19, 2016, 10:16:26 AM10/19/16
to Puppet Users
Hi Chadwick,

I'll definitely look a it soon, but can you explain what the lines do?

What would key_name be?

Thanks!

Chadwick Banning

unread,
Oct 20, 2016, 7:56:03 AM10/20/16
to Puppet Users
create_resources is a function that just loops through a hash of resources and adds them to the catalog. You can set any key name you want in Hiera and look it up directly with the hiera* functions. You can do something like this:

class profiles::postfix {
  include ::postfix
  $configs = hiera('profiles::postfix::configs')
  create_resources('postfix::config', $configs)
}

Then just set the 'profiles::postfix::config' key containing the settings you want anywhere in your Hiera hierarchy. The hiera function lookup will retrieve the value and this value gets passed to the create_resources function that will auto-generate the postfix::config resources.
Reply all
Reply to author
Forward
0 new messages