I am attempting to populate some configuration files from modules/apt_config/files using a defined resource and an array of files to install.

define aptfile($file) {
    file { $file: source => "puppet:///modules/${module_name}/etc/apt/${file}", }
aptfile{ [ 'apt.conf', 'sources.list', ]: }

According to this bug report, $module_name should be available. That part isn't causing me grief. What seems to be broken is that way that $file is not being populated when I call the resource; instead, I get the following error:

Must pass file to Apt_config::Aptfile[apt.conf] at /tmp/vagrant-puppet/modules-0/apt_config/manifests/init.pp:10 on node vagrant.home

Note that line 10 is the line containing the define aptfile definition.

The syntax is a little arcane. So, just in case I was specifying the file path backwards, I also tried this:

define aptfile($file) {
    file { "/etc/apt/${file}":
        source => "puppet:///modules/${module_name}/${file}",
aptfile{ [ 'apt.conf', 'sources.list', ]: }

with identical results. I know I could specify each file individually, but what do I need to do to make this loop work properly?


$file is an attribute. If you want to use the name of an instance of the definition (one of the items in the array you're using when declaring aptfile) you'd use $name.

So if you kept things as they are you'd do something like this:

aptfile {'somename':
  file => ['apt.conf', 'sources.list'],

However, what you're probably looking for is something like this:

define aptfile(
  $base_path = '/etc/apt',
) {
  file {"${base_path}/${name}":
    source => "puppet:///modules/${module_name}/files/${name}",

Note that $name comes from the title/name of the resource (define is essentially a custom resource of sorts) when you declare it. The applies to all resources. When you use an array when declaring a resource file {['f1.txt', 'f2.txt']: } you are simply condensing the declaration of multiple file resources...file {'f1.txt': }, file {'f2.txt': }. $name inside the body is the name of resource declaration in play while it's being parsed/processed.

Then call it like you were:

aptfile {['apt.conf', 'sources.list']: }

I find myself just using templates with content => template('modulename/somefile.erb') even if I don't need template functionality just because the path is more sane (with minimal additional overhead I imagine). Looking forward to source => adopting the same more reasonable path usage.


  • Thanks, Mark. I'm a little unclear as to where $name is being defined, though. I read through the documentation, and it seemed that I needed to define the parameter list explicitly in the definition like you're doing with $base_path.
    – CodeGnome
    Aug 10 '12 at 18:16
  • The first thing after the { is the $name. So, aptfile {'apt.conf': } would result in $name being 'apt.conf' within the definition body. However, in the case where you pass an array in then puppet will essentially make multiple instantiations of the resource for each name in the array (all with the same attributes). So, effectively aptfile {['apt.conf', 'sources.list']: } can be thought of as if you had seperately declared aptfile {'apt.conf': } and aptfile{'sources.list': }. Aug 11 '12 at 2:37

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.