Best way to do cross-module dependencies

219 views
Skip to first unread message

Dan Mahoney

unread,
Dec 7, 2015, 5:59:47 PM12/7/15
to Puppet Users
Hey all,

Everything I've done thusfar in creating my own custom modules has drilled some basics into my head -- these are right from the puppet web docs:

"A module’s classesdefined types, and plugins should all be related, and the module should aim to be as self-contained as possible.

Manifests in one module should never reference files or templates stored in another module."

I've also seen it preached hard that modules should attempt in all cases to be "portable".

So, with that said -- how is the best way to declare dependencies across modules?

For example, I have a one-file-per-rule firewall stack, where rules are placed in /etc/firewall.d, and loaded using a standardized ordering script -- this way my "httpd" module can add (and own) an "httpd" firewall rule.  How would I tell my web module that if that firewall type is in play, that it should add a file there, and reload the firewall?  How do I get the web module to only do this *if* that firewall type is in play, without directly *requiring* it?

I have a similar thing for syslog, where I can populate a directory and have individual packages own files in there.  Same question.

I also have a similar thing for logfile rotation.  Same question.

I don't want to build huge metaclasses all in site.pp -- nor does it seem sane to me to build meta-modules that do all the combining, although those *are* both ways forward.

Thanks,

-Dan

jcbollinger

unread,
Dec 8, 2015, 10:00:36 AM12/8/15
to Puppet Users
You're asking about how various modules can contribute pieces of system configuration that as a group are meant to be managed by another module.  The usual approach to such things is for the manager module to provide a defined type or a full-fledged custom type for other modules to use for the purpose.  For instance, a type representing a firewall rule, or a facility monitored via syslog, or a logfile that must be rotated.  You can see examples of this approach in the apache::vhost defined type provided by the puppetlabs-apache module, and in the firewall custom type provided by the puppetlabs-firewall module.  With that approach, the client modules freely declare whatever instances they want of that resource type provided by the manager module, with little or no need to be concerned with managing the central facility itself.

As to how to plumb up the details of such an approach, I suggest you look to the examples I offered, especially puppetlabs-apache.  One of the tools you likely will see used is the puppetlabs-concat module, which serves the purpose of managing files built up from individual pieces that are managed independently.  You probably will not need that, however, where you manage state as you seem wont to do -- with a separate file for each piece of managed state.  Where the problem can be broken down like that, a defined type representing such managed files seems natural and fairly easy.

There are other flavors of cross-module dependency, too, some of them having been subjects of considerable controversy in the past.  Those controversies have not been altogether stamped out, but their essential problems have been greatly reduced by the emergence and broad acceptance of automatic data binding, and by adoption of strategies that tend to reduce conflicts, such as the "Roles and Profiles" pattern.  I leave discussion of those for another day.


John

Thomas Müller

unread,
Dec 11, 2015, 9:47:16 AM12/11/15
to Puppet Users


Am Montag, 7. Dezember 2015 23:59:47 UTC+1 schrieb Dan Mahoney:
Hey all,

Everything I've done thusfar in creating my own custom modules has drilled some basics into my head -- these are right from the puppet web docs:

"A module’s classesdefined types, and plugins should all be related, and the module should aim to be as self-contained as possible.

Manifests in one module should never reference files or templates stored in another module."

I've also seen it preached hard that modules should attempt in all cases to be "portable".

So, with that said -- how is the best way to declare dependencies across modules?


Use the roles/profiles pattern. Parametrize httpd and firewall rules from the profile. So httpd and the firewall module are completly separeted.

- Thomas

Reply all
Reply to author
Forward
0 new messages