overriding parts of a collection of defined resources

54 views
Skip to first unread message

David

unread,
Feb 19, 2012, 12:43:19 AM2/19/12
to puppet...@googlegroups.com
Hi-

Being relatively new to the language, I find myself in a situation where it seems like there must be an elegant way to handle this situation using the DSL, but I'm not really certain what it could be. 

I'm trying to describe a configuration that contains 20-30 or so file { } resources, all with the same attributes except for their mode and source. I could write them all out explicitly like this:

file { '/etc/passwd':
 uid => root,
 gid => root,
 mode => 0644,
 source => 'puppet:///modulename/etc/passwd',
}
...
file { '/var/lib/someotherfile':
 uid => root,
 gid => root,
 mode => 0400,
 source => 'puppet:///modulename/var/lib/someotherfile',
}

but that seems unnecessarily repetitive. I originally started down the path of writing something like this (ignore the difference in the mode attribute for a moment):

file { [ '/etc/passwd', ... , '/var/lib/someotherfile' ]:
 uid => root,
 gid => root,
 mode => 0400,
 source => "puppet:///modules/modulename/${title}",
}

but this bug: http://projects.puppetlabs.com/issues/5259
and this mailing list discussion:  https://groups.google.com/d/topic/puppet-users/bj_uPi_WxC4/discussion

helped me understand that that attempting to reference the title attribute (the file's namevar) would never work and I would have to use a defined resource instead. Taking Nan's advice in that thread, I then wrote:

define basefiles::conf($mode){
       $serversource = 'puppet:///modules/modulename'

       file { "${name}":
           source =>"${serversource}/${name}",
           owner  => root,
           group  => root,
           mode   => "${mode}"
   }
}

basefiles::conf { '/etc/passwd:' mode => 0644 }
...
basefiles::conf { '/var/lib/otherfile:' mode => 0400 }

.... and that's all groovy. The manifest looks concise and readable.

But here's where I stare at a tree and get lost in the forrest: the manifest I'm writing contains my base list of files. On some of my machines, I will want to override that base and substitute a different copy of one or two files from that list (e.g. I will want a different /etc/passwd put in place).

Further research leads me to this discussion of overriding defined resources and the futility of trying:

https://groups.google.com/d/topic/puppet-users/SDa1F817UBA/discussion

That discussion leads me to believe it isn't possible to override defined resources in the same way you might with a class. That makes me think I have to either: 
   a) move the files I might want to override out to their own separate class or
   b) add some logic to the resource definition to do something magical for certain invocations

Both of these options seem icky to me because it means the base module has to be coded in such a way that it has some specific knowledge about when and how it might be overridden. That feels like bad coding mojo to me. 

So, is there a concise way to describe a collection of file resources, yet be able to override parts of that collection definition in an equally elegant fashion? My instinct says there must be (and it is probably palm-meets-forehead simple), but I can't seem to determine what that might be. Thanks for any help you can offer!

    -- dNb

Marc DiBlasi

unread,
Feb 19, 2012, 9:12:39 AM2/19/12
to Puppet Users
I have a couple pointers that may help you.

- The default user and group is root.
- You can set type defaults like this: File { user => "root", group =>
"root"} and if you put this in a class, it only applies to the class.
If you put it in site.pp, it applies globally.
- You can define multiple resources in the same declaration separated
by a semi-colon. i.e. file { "/etc/passwd": source => "..."; "/etc/
group": source => "..."}

Hopefully these allow you to speed things up a bit.

Aaron Grewell

unread,
Feb 19, 2012, 4:50:22 PM2/19/12
to puppet...@googlegroups.com

Resource defaults may help you. If you create a default file resource :

File{


  owner => root,
  group => root,

  mode => 644,
}

The file resources in the class will assume these defaults unless their own definition specifies otherwise. For large numbers of resources of the same type there is also a more concise declaration style :
file {
  /etc/passwd:
    source => 'puppet:///someplace ';
  /etc/other:
    mode => 400,
    source => 'puppet:///someplace/else';
}

Combining these two should be a relatively efficient way of getting there.

--
You received this message because you are subscribed to the Google Groups "Puppet Users" group.
To post to this group, send email to puppet...@googlegroups.com.
To unsubscribe from this group, send email to puppet-users...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/puppet-users?hl=en.

Nan Liu

unread,
Feb 19, 2012, 5:03:03 PM2/19/12
to puppet...@googlegroups.com
On Sat, Feb 18, 2012 at 9:43 PM, David <dnblank...@gmail.com> wrote:
> basefiles::conf { '/etc/passwd:' mode => 0644 }
> ...
> basefiles::conf { '/var/lib/otherfile:' mode => 0400 }
>
> .... and that's all groovy. The manifest looks concise and readable.
>
> But here's where I stare at a tree and get lost in the forrest: the manifest
> I'm writing contains my base list of files. On some of my machines, I will
> want to override that base and substitute a different copy of one or two
> files from that list (e.g. I will want a different /etc/passwd put in
> place).
>
> Further research leads me to this discussion of overriding defined resources
> and the futility of trying:
>
> https://groups.google.com/d/topic/puppet-users/SDa1F817UBA/discussion
>
> That discussion leads me to believe it isn't possible to override defined
> resources in the same way you might with a class. That makes me think I have
> to either:
>    a) move the files I might want to override out to their own separate
> class or
>    b) add some logic to the resource definition to do something magical for
> certain invocations

You can't override define definition, but you certainly can still
override define resources. So the first thing is you should do is to
have source as part of the parameter.

define basefiles::conf(
$mode = '0644',
$source = "puppet:///modules/${caller_module_name}/${name}"
){
file { "${name}":
    source =>$source,
   mode   => $mode,
}
}

Now you can certainly write a class that can be inherited and overritten:
class myfiles {
basefiles::conf { '/etc/passwd': }
}

class myfiles::sub inherits myfiles {
Basefiles::Conf['/etc/passwd'] {
source => 'something new',
}
}

But the following would probably be more flexible, either hard code a hierarchy:

define basefiles::conf(
$mode = '0644',
$source = ["puppet:///modules/${caller_module_name}/${hostname}/${name}",
"puppet:///modules/${caller_module_name}/${name}"]
){
file { "${name}":
    source =>$source,
   mode   => $mode,
}
}

Or just use hiera function (see our recent blog posts):

define basefiles::conf(
$mode = '0644',
$source = hiera($name, "puppet:///modules/${caller_module_name}/${name}")
){
file { "${name}":
    source =>$source,
   mode   => $mode,
}
}

HTH,

Nan

David

unread,
Feb 20, 2012, 9:00:02 PM2/20/12
to Puppet Users
Thanks Aaron, Marc and Nan for your responses. All of your tips are
very useful. I think Nan's suggestion nails it for me and helps clear
up a misunderstanding I had about what could be overridden. I think
the part of Nan's response that I like better than using the
"collapsed" way of writing definitions and/or using resource defaults
is it let's me construct the source attribute from the resource title
(${name}) vs. having to specify the file path twice. I realize this is
a little thing that is just a matter of taste so it is great to learn
of the other options. Plus, I've had my eye on hiera for a while, this
might be a good place to put it in practice.

Thanks again to everyone for their help.

-- dNb
Reply all
Reply to author
Forward
0 new messages