www.nice-site.co.uk0:
source: kitten-pics
target:
www.nice-site.co.uk/site-content/user-data
That duplicates data even more, however. You could improve it further (IMO) by flattening it a bit and pushing down the site info, such as:
directorymap:
artificial-id-0:
source: dodgy-uploaded-jpegs
site:
www.blah.com
target:
wp-content/uploads
artificial-id-1:
source: disturbing-home-videos
site:
www.blah.com
target:
wp-content/filth
artificial-id-2:
source: kitten-pics
site:
www.nice-site.co.uk target:
site-content/user-data
Note that now the data structure is a hash whose keys are suitable identifiers for resources you want to manage, and whose values are hashes of the desired properties of those resources. That's exactly what you need for the create_resources() function.
To use create_resources(), you also need a resource type to accept those parameters, and since there is no built-in type that does what you want, your best bet would be a defined type:
define content::link($source, $site, target) {
file { "${content::base_directory}/${site}/${target}":
ensure => link,
target => "${site}/${source}"
}
}
Note that variable $content::base_directory must be defined elsewhere (in a separate class "content", in this case). This is essential because the base directory is not included in your data, yet is needed to correctly identify the link's full path.
With those pieces in place, you can tie it all together as simply as this:
create_resources('content::link', hiera('directorymap'))
If you don't like the revised form of your data that I suggested, or for future problems, there are at least a few other tools you should have in your toolbox:
1) A Puppet function to extract an array of keys from a hash. You can write your own if you like (it's easy), but there is one ready-made in Puppetlabs's useful 'stdlib' module (
https://github.com/puppetlabs/puppetlabs-stdlib).
2) Defined types. Learn them, live them, love them. And especially, know that inside a defined type body, you can refer to instances' given titles via the automatic $name and/or $title variables.
3) Multiple resource declaration syntax. If the title of a resource declaration is an array -- either a literal one, or a variable with an array value -- then it means one resource for each element of the array, with the corresponding element as resource title. For instance,
file { [ '/tmp/foo', '/tmp/bar' ]: ensure => present }
is equivalent to
file { '/tmp/foo': ensure => present }
file { '/tmp/bar': ensure => present }
That can be combined in useful ways with (1) and (2). In particular, you can extract an array of hash keys, declare instances of a defined type with those titles, and in the body of the defined type use the title to extract and work with one element of the original hash. So, if you wanted to avoid the create_resources() function (but use the same data structure) then you could do something like this instead:
$keys = keys($content::directories)
content_link2 { $keys: }
define content::link2() {
$source = $content::directories[$name]['source']
$site = $content::directories[$name]['site']
$target = $content::directories[$name]['target']
file { "${content::base_directory}/${site}/${target}":
ensure => link,
target => "${site}/${source}"
}
}
John