I have a set of config files that need to be deployed to multiple locations on each server, each with different content, however they all share the same location structure. I'm trying to reduce the amount of replication I have in my manifests by making a common class which can be used multiple times.
Here's a simplified example of the file structures:
/home/bob/config/files.cfg
/home/bob/config/settings.cfg
/home/sue/config/files.cfg
/home/sue/config/settings.cfg
/home/ann/config/files.cfg
/home/ann/config/settings.cfg
And here's the manifest I've written.
class config-generic {
file { "/home/$name/config/files.cfg":
owner => $name,
group => $name,
source => "puppet://puppet.domain.com/files/home/$name/config/files.cfg",
mode => 644,
}
file { "/home/$name/config/settings.cfg":
owner => $name,
group => $name,
source => "puppet://puppet.domain.com/files/home/$name/config/settings.cfg",
mode => 644,
}
}
On the first use of the class it works fine.
node "client1", "client2" {
class {'config-generic':
name => 'bob',
}
}
However when I come to use the class again it errors because the class is already defined.
(Error 400 on SERVER: Duplicate definition: Class[config-generic] is already defined)
node "client1", "client2" {
class {'config-generic':
name => 'bob',
}
class {'config-generic':
name => 'sue',
}
}
Question: I understand the problem - however what's a better way of reducing replication in my manifests? I'm trying to avoid having to define a 'file' entry for each user for each file.
What you need is not a class, but a definition, since you want to make several instances of them, something like:
and call it with:
You might also want to use a template if there's only small differences, instead of duplicating the source files.