Parameters vs Defined Types as Interface to Modules

asked 2017-05-03 16:51:22 -0600

ljkimmel9903 gravatar image

I've [somewhat] recently started developing Puppet modules for use with Foreman and have gone through a couple iterations. At first I was developing a large, broadly-scoped module for a specific purpose. I soon found that in order to provide any amount of customizable behavior I would have to provide so many parameters that it was unwieldy.

Therefore, I moved into using much more purpose-specific modules (e.g. sshd, aide, chrony, etc). These modules provide a lot of flexibility but then you lose the centralized view of the things the configuration items for a specific application or workflow require.

I recently came across some modules on the Forge that got me considering using modules with defined types exposing their functionality. I think this seems to be the ultimate way to do things because it allows the same flexibility as the purpose-specific module setup while essentially requiring you to have another module for your application or workflow which utilizes the defined types from all of your defined type augmented modules.

However, I would very much prefer an all or none solution. That is I don't want to have defined type modules for pieces of a workflow but have to directly configure parameters on other modules for other pieces of my workflow. Unfortunately, the module availability on the Forge seems to be about 50/50 at best (that is maybe half the modules are built with defined types). Also, the use of defined types, at least when dealing with config files, essentially means using either Augeas or Concat. For complex configuration files this can often be quite difficult (which I think is why many people default to templates).

So, in order to use the defined type route it would seem that one needs to invest a lot of time in developing custom modules. It seems easier and not much worse to just settle for purpose-scecific parameterized modules. This has the side effect of giving a better centralized view of all the configurations applicable to a given process or library.

I'm very interested in hearing about other peoples' experiences and recommendations.

edit retag flag offensive close merge delete


I believe that using the roles and profiles pattern gives you the set of parameters with defaults for different sets of modules, that you can tailor per type of server or tech stack, and you should compose a few profiles into each role. That helps give you a uniform interface for consumers.

DarylW gravatar imageDarylW ( 2017-05-07 22:27:37 -0600 )edit

Thanks for the input, Daryl. I think you're right that what I'm looking to do looks like the roles/profiles pattern. However, I'm concerned about what happens when (2) or more modules want to configure a common file (say, sshd_config).

ljkimmel9903 gravatar imageljkimmel9903 ( 2017-05-08 07:27:28 -0600 )edit

It's going to be very difficult to craft the sshd module to be able to deal with conflicting values. It seems to make most sense to just pass all required parameters to the sshd class, in this case. And, if that's the case, it sort of breaks the whole profiles pattern for me.

ljkimmel9903 gravatar imageljkimmel9903 ( 2017-05-08 07:28:23 -0600 )edit

I haven't looked specifically at the sshd module, but I agree with you on using defined types that can get 'rolled up' by the main class for a module. I've seen that pattern used for managing log rotation in profiles, one 'define' per log file to manage, and the main class to assemble that config

DarylW gravatar imageDarylW ( 2017-05-08 09:19:16 -0600 )edit

Using something like to build the 'parts' and then assemble them into a template in the main module, etc..

DarylW gravatar imageDarylW ( 2017-05-08 09:20:18 -0600 )edit