1
votes

I have a puppet config that correctly installs a file. I want it to install several files. The config looks roughly like this (in the part that is relevant here):

$stuff = hiera('stuff')
$site_filename = $stuff['site_file']

file { "/path/to/my/file/called/$site_filename":
  ensure  => present,
  owner   => 'the-owner',
  group   => 'the-group',
  mode    => 644,
  source  => "puppet:///modules/this-module/$site_filename",
  require => [Package['something'],
      User['someone']]
}
file { "/path/to/my/symlink/called/$site_filename":
  ensure  => 'link',
  target  => "/path/to/my/file/called/$site_filename",
  require => Package['something'],
}

Works great, the right file is installed on the right host. But I'd now like to install a variable number of (very similar) files, the number being different on each host.

My hiera files currently look like this:

stuff:
  site_file: "hey-i-am-the-site-file-on-host-awesomeness"

In principle, I want to say something like this:

stuff:
  site_file: ["hey-i-am-the-site-file-on-host-awesomeness",
              "i-am-also-a-site-file-for-awesomeness",
              "do-not-forget-me-too",
              "someday-you-will-want-me-as-well"]

And here I am hitting the limits of my puppet and hiera knowledge. I understand that when I think I should iterate in puppet, I'm probably wrong, but I'm a bit confused how to do this.

Any pointers on how to do it or what to read about to learn?

1
It's hard to believe that what you present "Works great" when it is syntactically incorrect and presents duplicate resources. Let's start with something that actually could work, shall we?John Bollinger
Additionally, which version of Puppet is this for? An answer for Puppet 3 (with future parser disabled) could be substantially different from one for Puppet 4.John Bollinger
This is puppet 3.7.2. Given that I've said this is a snippet of a manifest, what is syntactically incorrect? (Ah, in simplifying, I did duplicate the filename, fixed.)jma
You didn't mention whether you are using the future parser or not though.Matt Schuchard
Ah, sorry. I am not.jma

1 Answers

2
votes

Puppet 4 and has some iteration functions that would be applicable here, and these are available also in recent Puppet 3 with the future parser enabled. They are not available in Puppet 3 without the future parser, however, so you need a different solution.

The classic way to approach problems such as this is to rely on the fact that a resource declaration in which the title is an array (literal or array-valued variable) declares a separate resource for each element of the array. This is often combined with a defined type as the resource to directly declare. This combination is roughly equivalent to a foreach loop over the array elements, with the defined-type body as its body. Example:

define mymodule::sitefile() {
    file { "/path/to/my/file/called/$title":
      ensure  => present,
      owner   => 'the-owner',
      group   => 'the-group',
      mode    => 644,
      source  => "puppet:///modules/mymodule/$title",
      require => [Package['something'], User['someone']]
    }

    file { "/path/to/my/symlink/called/$title":
      ensure  => 'link',
      target  => "/path/to/my/file/called/$title",
      require => Package['something']
    }
}

# ...

$stuff = hiera('stuff')
mymodule::sitefile { $stuff['site_file']: }