What we're trying to do is generate firewall rules (puppetlabs/firewall) for iptables. Our nodes are grouped like so conceptually:
-- site1
---- shared1
------ specific1
------ specific2
---- shared2
------ specific3
------ specific4
The node "specific4" will always need to access port 8080 on "shared2" and port 10000 on "site1". "specific1" likewise will need to access 8080 on "shared1". The rules are always going to be the same per node but they will rely on which group they are apart of.
I'm struggling to find a way to represent this in hiera without duplication. Is it possible to get facts from a completely separate node?
I think I want to be able to do something like this (simplified):
--
hosts:
host specific4:
rules:
rule:
port: 8080
ip: get_ip(get_my_shared())
But obviously, you can't call functions from a yaml
file. Would the best way to go about this be using custom facts? I'm haven't actually used hiera yet - so I'm unsure of best practices and what not. Any gentle pushes in the right direction would be most appreciated.
Edit:
This is the solution I've gone with, but if I can use exported resources I can remove the dependency on puppetdb-query.
# helper for creating rules from an array
define firewall_rules($port, $service_type) {
$source = $name
firewall { "$port $service_type $source":
proto => 'tcp',
dport => $port,
state => 'NEW',
source => "$source",
action => 'accept'
}
}
class profile::specific inherits profile {
$site = hiera('site')
$shared = hiera('shared')
$query = "site=\"$site\" and shared=\"$shared\""
$shared_hosts = query_nodes($query)
$specific_port = hiera('specific_ports', '8080')
firewall_rules { $shared_hosts:
port => $specific_port,
service_type => 'SPECIFIC'
}
}
I then export the site
and shared
facts based on hiera data, and using puppet-stdlib
to load them from file
resources on the host.
class profile::facts {
$site = hiera('site', 'none')
$shared = hiera('shared', 'none')
$specific = hiera('specific', 'none')
$role = hiera('role', 'none')
$grouping = "site=$site\nshared=$shared\nspecific=$specific\nrole=$role"
notify { "facts being set: $grouping ": }
file { ['/etc/facter/', '/etc/facter/facts.d/']:
ensure => directory,
owner => 'root',
group => 'root'
}->
file { '/etc/facter/facts.d/grouping.txt':
ensure => file,
owner => 'root',
group => 'root',
mode => '0775',
content => $grouping
}
}
As I said, this works, but I'd prefer to use exported resources if possible. The problem I ran into was that the resource doing the exporting couldn't also export its own IP/Host for collection. Perhaps I missed something, but I don't think it's possible, as the exporting happens when the resource is parsed, not when the node that contains that resource is realized.