Hello,
I'm trying to come up with a generic wrapper class for use with hiera so
that I can have a service that is completely managed and configured via
hiera and its own puppet module to be notified by Puppet of changes to a
file or other resource managed by a different class/module. The example
I'm using here is the management of /etc/security/limits.conf for a
service account that only needs to be changed on certain systems.
[Yes, I could put the configuration of the limits.conf into the module
for this particular service, but I'm trying to keep the dependencies of
that module to a minimum so that it is portable.]
Picture the following yaml hiera data for a node (the basic::limits
class is a wrapper for the puppet-limits module):
---
classes:
- foo
- basic::limits
foo::option_1: true
basic::limits::instance:
foo_limits:
user: 'foobar'
limit_type: 'nofile'
hard: '10000'
soft: '10000'
If I create a separate class, I can do the resource ordering normally as
expected:
class tmp {
Limits::Limits['foo_limits'] ~> Service['foo']
}
This separate class ensures that changes to the limits configuration
properly notifies the service to restart. However, I don't want to
clutter up our puppet configuration with a lot of singular
modules/classes just for resource ordering and would like to be able to
define it just in hiera. Therefore, I attempted to create a generic
wrapper define for resource ordering (the following doesn't actually
work, will get to the error):
#Define for resource ordering or subscribing
define basic::order_resource::ordering (
$resource1_type = undef,
$resource1_name = undef,
$resource2_type = undef,
$resource2_name = undef,
$notify = false,
){
if $notify {
$resource1_type[$resource1_name] ~> $resource2_type[$resource2_name]
} else {
$resource1_type[$resource1_name] -> $resource2_type[$resource2_name]
}
}
And a wrapper class to use it via hiera:
#basic::order_resource
class basic::order_resource ($instance){
$real_instance = hiera_hash(basic::order_resource::instance)
create_resources(basic::order_resource::ordering, $real_instance)
}
Sample yaml in hieradata:
basic::order_resource::instance:
foo_limits_sub:
resource1_type: Limits::Limits
resource1_name: foo_limits
resource2_type: Service
resource2_name: foo
notify: true
However, as I already stated, my generic define doesn't actually work
and returns the following error because Puppet can't/doesn't evaluate
the variable as an actual resource type:
Error: Could not retrieve catalog from remote server: Error 400 on
SERVER: resource1_type is not a hash or array when accessing it with
foo_limits at
/etc/puppet/modules/basic/manifests/order_resource/ordering.pp:10 on
node vagrant-centos-6
What am I missing to get Puppet to evaluate the $resourceX_type
variables as a resource type [e.g: File, Service, etc.] to get this to
work? I'd like to try do it this way so that I don't have to make a
very long, messy and hard to maintain class with a lot of nested case
statements to perform a similar function. That is, unless there's some
other method that I haven't considered/found/thought of.
sample nested case code (this will get ugly fast and isn't very flexible):
case $resource1_type {
'File': {
case $resource2_type {
'Service': {
if $notify {
File[$resource1_name] ~> Service[$resource2_name]
} else {
File[$resource1_name] -> Service[$resource2_name]
}
}
default: {fail("Unknown resource type '${resource2_type}' for
\$resource2_type")}
}
}
default: {fail("Unknown resource type '${resource1_type}' for
\$resource1_type")}
}
Thank you for taking the time to wade through my lengthy question.
--
Joseph Swick <
joseph...@meltwater.com>
Operations Engineer
Meltwater Group