yamlpuppethiera

Puppet: Override resource-like class declaration


Hoping someone with more puppet experience than me can give me some advice with a config I'm attempting.

I'm using saz/ssh as the module for this.

My goal

  1. Use this module to create a default ssh config, that gets pushed to all redhat 7/8 servers.
  2. Allow override of individual ssh options, on an individual server basis, through hiera

to achieve #1 I've created my own 'module' which declares the ssh::server class, and defines my options. I believe this is called a resource-like class declaration. (Shortened the code for readability)

#
class profiles::sshd::config {
  class { 'ssh::server':
    validate_sshd_file   => true,
    storeconfigs_enabled => false,
    options              => {
      'Port'                      => [22],
      'AddressFamily'             => 'any',
      'ListenAddress'             => '0.0.0.0',
      'Protocol'                  =>  '2',
      'HostKey'                   => ['/etc/ssh/ssh_host_rsa_key', '/etc/ssh/ssh_host_ecdsa_key','/etc/ssh/ssh_host_ed25519_key'],
      'RekeyLimit'                =>  'default none',
      'SyslogFacility'            => 'AUTHPRIV',
      'LogLevel'                  => 'INFO',
    }
  }
}

I then include this 'module' in my base. This works well, until I want to override any of these options on an individual server basis. I can't get hiera to work.

declaring

ssh::server::options:
    Port: [2222]

in the fqdn yaml file of a server for example, does nothing. If I include the ssh::server module directly, not through my own class, the hiera overrides work.

I've tried all sorts of syntax for the hiera overrides, but never get any output on a puppet run, unless I've using the class directly. For example I've tried:

ssh::server:options:
profiles::sshd::config:
profiles::sshd::config::ssh::server:
profiles::sshd::config::options:
profiles::sshd::config::ssh::server::options:

Is there a better way I can do what I want, or can anyone offer assistance on how I can declare hiera overrides in this manner?

Any help would be incredibly helpful


Solution

  • to achieve #1 I've created my own 'module'

    ... and in it, a class named profile::sshd::config ...

    which declares the ssh::server class, and defines my options. I believe this is called a resource-like class declaration.

    Yes, you have written a resource-like class declaration. This is usually a bad idea. There are several reasons, but among them is that ...

    [when] I want to override any of these options on an individual server basis[,] I can't get hiera to work.

    Class parameter values specified via a resource-like class declaration take precedence over values specified via any of the other available ways, including Hiera data. You cannot override them.

    You have two main alternatives:

    1. Give your wrapper class its own parameter for each of the wrapped class's parameters that you want to be able to customize. Use those to initialize the wrapped class:

      class profiles::sshd::config(
          Boolean $validate_sshd_file = true,
          Boolean $storeconfigs_enabled = false,
          Hash $options = { ... },
      ) {
        class { 'ssh::server':
          validate_sshd_file   => $validate_sshd_file,
          storeconfigs_enabled => $storeconfigs_enabled,
          options              => $options,
        }
      }
      

      Supposing that you then declare class profiles::sshd::config via an include-like declaration, you can customize its parameters via Hiera. But note that

    2. If you change to an include-like declaration of class ssh::server, then you can both define default parameters for it via Hiera and customize its parameters via Hiera.

    There is a middle road, too: given a resource-like declaration of ssh::server, you can use Hiera to customize any and all parameters other than those specified in its declaration. Thus, if there are parameters that you want to avoid being available for customization, then you could consider declaring them (only) explicitly via resource-like class declaration, and rely on Hiera for the rest. So note, however, that this still leaves you open to some of the other issues with resource-like class declarations (which would be a separate question).