I don't think there is a right way to do the following (yet) in Puppet, but this strikes me as desirable.
I want my classes to be able to influence the content of a templated file from another class so that we can both avoid duplicating information, and put the info where it belongs.
For instance we have an "iptables" class, and various service classes, such as "postfix", "webappfoo" etc.
class webappfoo {
$myfwrules +> [ "-A INPUT -p tcp --state NEW -m tcp --dport 80 -j ACCEPT" ]
include apache
}
node webappserver {
include webappfoo
include iptables
}
But this does not work; the $myfwrules array only contains that line within webappfoo.
Note that a class can read into another one; for instance here iptables could just read $iptables::myfwrules; but I don't want iptables to have to know about webappfoo.
This is a scoping issue. From the language tutorial:
So
$myfwrules
is scoped into the class it's defined in. In your case you're scoping it into classwebappfoo
, where it has no knowledge of any previously defined$myfwrules
. You can bodge around this but a better approach might be to use definitions. Something like this (untested, YMMV, etc):This way you have a reusable way to add rules into your classes without needing to define variables and worry about scope. You'll end up with a bunch of
Exec
resources (Exec["rule-webappfoo"]
,Exec["rule-postfix"]
) representing nodefoo
's ruleset.Also see the ready-baked iptables modules.
Edit: this is just an example to demonstrate how definitions might be used. It's not meant to be problem-free solution. For a start, there are issues around the order in which rules might be applied (could use
before
/after
, perhaps), and the efficiency of calling/sbin/iptables
every time.I decided to use templates and multiple concatenation to build iptables rules. e.g.
It's not pretty, and it requires a dedicated iptables.hostname.erb file for each computer. But it's stupid simple.
Also read up on Puppet's store configs and multiple file concatenation.
I haven't touched puppet for some time, so my syntax may be a bit rusty. Should "+>" be "+="? Anyway, have you tried this?
This iptables module seems to be the only way to do what I want; it's basically a script which takes files in an iptables.d/ directory and builds /etc/sysconfig/iptables from it. This is probably what I'm going to use; but I feel that this kind of pattern should be possible in Puppet itself.