Ask Your Question

Trying to use namevar list with $name or $title variable

asked 2014-08-07 13:58:06 -0600

myth0s gravatar image

updated 2014-08-09 12:37:00 -0600

ramindk gravatar image

I want Puppet to ensure some files in a directory. I am using Foreman to set the array of files that should be present for a host.

What I though is that I could use namevar iteration ( ) to have the file type iterate over an array like ["file1.txt","image.png"]

file { $user_files:
    # this should get executed twice, right? once for "file1.txt" and once for "image.png"
    path    => "/tmp/dir/$title",
    # I expect $title to be "file1.txt" on the first iteration and "image.png" on the second
    source  => "puppet:///modules/someModule/$title", # same as above
    ensure  => file,
    mode    => '0644',

The expected result is for Puppet to take the file at puppet:///modules/someModule/file1.txt and place it /tmp/dir/file1.txt. It should do the same thing with image.png.

Error: Failed to apply catalog: Cannot alias File[file1.txt] to ["/tmp/dir/myPuppetClass::config"]
at /etc/puppet/environments/development/modules/someModule/manifests/config.pp:18;
resource ["File", "/tmp/dir/myPuppetClass::config"] already declared at
edit retag flag offensive close merge delete

4 Answers

Sort by ยป oldest newest most voted

answered 2014-08-08 07:46:00 -0600

myth0s gravatar image

updated 2014-08-09 21:41:54 -0600

This guy ran into the issue too:
(See Stefan explanation below if you want to know why this happens)

So I instead went with this code:

define file_array() {
    file { $name: 
        path    => "/tmp/dir/$name",
        source  => "puppet:///modules/someModule/$name",
        ensure  => file,
        mode    => '0644',

  file_array{$arrayReceivedFromParamsClass: }
edit flag offensive delete link more

answered 2014-08-08 16:06:42 -0600

Stefan gravatar image

myth0s showed the correct way on how to do it. I just want to add that the observed behaviour is intentional:

A resource declaration does not create a new scope. A class for example or a definition declares a new scope and in that scope, the variable $name is set to the classe's or define's name. So when you use

file { "/tmp/${name}":
  content => "my path is /tmp/${name}",

both $name would resolve to the class' name where this resource is declared in (and would be undesirable if both usages of $name would lead to different results.

Another person once described it like this: If you think of the short script "a=30; sin(a)" would you expect the sin function to replace a with 30 or the caller? It would be the latter and in the same way the resource declaration works here.

edit flag offensive delete link more

answered 2014-10-01 11:59:25 -0600

I used the solution myth0s postet and bumped into problems when using ordering in dependance of other variables because the variables wouldn't exist within the scope of the define. To solve this I simply transferred the content of those variables with parameters.

$otfDirectory = "/usr/share/fonts/opentype"
file { $otfDirectory: ensure => directory }

$otfFonts = [ "SourceCodePro-Black.otf",
              "SourceCodePro-Semibold.otf" ]

define install_font( $directory = undef ) {
  file { $name:
    source      => "puppet:///production/fonts/${name}",
    path        => "${directory}/${name}",
    ensure      => file,
    require     => File[$directory],

install_font { $otfFonts: directory => $otfDirectory }
edit flag offensive delete link more

answered 2014-08-08 10:32:06 -0600

binford2k gravatar image

It might be simpler for you to manage a directory recursively. See the file type for more information:

edit flag offensive delete link more

Your Answer

Please start posting anonymously - your entry will be published after you log in or create a new account.

Add Answer

Question Tools


Asked: 2014-08-07 13:58:06 -0600

Seen: 11,340 times

Last updated: Aug 09 '14