On Thursday, January 22, 2015 at 4:09:37 PM UTC+1, jcbollinger wrote:
>
>
>
> On Wednesday, January 21, 2015 at 11:36:25 AM UTC-6, Alessandro Franceschi 
> wrote:
>>
>> Given that:
>> - I've used nodes inheritance with profit for years, in the past
>> - Now I mostly prefer a nodeless setup (with or without ENC)
>> let me spam the list with a fragment of my book Extending Puppet on the 
>> topic, as it contains some (controversial?) points of view I'm curious to 
>> hear opinions about (note: it was written before knowing about Puppet4 
>> removal of nodes' inheritance, so now, I would not use it in any case) :
>>
>>   Node inheritance done right 
>>
>> Node inheritance has a bad reputation. All the Puppet books around, even 
>> the ones of a giant like James Turnbull, and the official Puppet Labs 
>> documentation describe it as a bad practice, and this puzzles me, as I 
>> had successfully used this approach for years. 
>>
>
> Me, too.  I'm sad to see it go, though I won't be too greatly 
> inconvenienced.
>
>  
>
>> The main problem, I think, has been a documentation issue, as it's not 
>> well explained to users that node inheritance makes sense when used to 
>> assign variables, but it is dangerous when used to manage class grouping. 
>>
>
> I think the main issue is not so much documentation, but naming / keyword 
> choice.  The actual behavior of Puppet node inheritance is reasonably well 
> documented, and I have used it successfully for class grouping for years.  
> The concept of inheritance and the word "inherit[s]" don't very well fit 
> the actual implementation of node inheritance in Puppet (<4), however.  
> Despite Puppet's documentation, some people make wrong assumptions about 
> node scopes when inheritance is involved.  I think this tends to occur 
> where their thinking is colored by experience with the OO concept of 
> inheritance (and this is one aspect of a larger problem of Puppet adopting 
> OO terminology for its own, slightly different, concepts).  Specifically, 
> you get in trouble with node inheritance when you suppose that a child node 
> can influence anything declared by its parent node, other than via explicit 
> override.
>

Very good points.
I suppose we all agree, Luke included, that OO naming for non OO concepts 
has generated a lot of confusion.
Also, I'd say, that documentation, which is now great, was much less clear 
in the past (remember the wiki?) and different patterns were tested and 
explored.
Many have suffered with nodes inheritance and dynamic variables scoping in 
the past, and I suppose this is the reason of their progressive removal.
 

>
>  
>
>> Let's see an example of a wrong approach to node inheritance: 
>>
>>    node default {
>>      include general
>>
>>    }
>>    node 'it' inherits default {
>>
>>     $zone = 'it'
>>    } 
>>
>>    node 'web01.it.example.com' inherits 'it' {
>>      $role = 'web'
>>      include role::web
>>
>> } 
>>
>> The issue in this extremely simplified example is that when Puppet parses 
>> general, it hasn't set the $role and $zone values, and the result for 
>> the resources declared in general, depending on them, would probably not 
>> be what was expected. 
>>
>> When node inheritance is used only to set and eventually override 
>> variables and not to include classes, none of these problems are present: 
>>
>>    node basenode {
>>      dns_server = '8.8.8.8'
>>
>>    }
>>    node 'it' inherits basenode {
>>
>>       $zone = 'it'
>>     $dns_server = '1.2.3.4'
>>    }
>>
>>    node 'web01.it.example.com' inherits 'it' {
>>      $role = 'web'
>>      include site
>>
>>     } 
>>
>
> The rule there being that only leaf nodes should declare any classes, 
> yes?  That's actually quite nice and sensible, with only one limitation I 
> see: it is hard to extend the inheritance tree once you decide which nodes 
> are leaves.  In practice, that limitation is probably not a big deal.
>

Well, the leaves are always the single hosts, so if you need to introduce 
new layers in the inherited nodes, you still can (it's like adding a 
hierarchy in Hiera) 

>
> Another safe general approach to node inheritance is to altogether avoid 
> node-scoped variables (along with avoiding resource-like class declarations 
> in node blocks, but you should do that in any case).  With that approach 
> you can create an insanely complex, multi-level node inheritance tree, with 
> no worries that you will come to grief from it, even when you later modify 
> or extend it.
>
>  
>
>>   Now, I would not use this approach anymore, as it requires an include 
>> line for each node, and it sets variables at node scope. This implies that 
>> while they can be used in the node's classes, we cannot refer to them 
>> with a fully qualified name, and so, for example, we cannot use them on 
>> a Hiera hierarchy.
>>
>> Still, in situations where an ENC and Hiera are not used and the node 
>> names are not descriptive, this is a working and effective way to 
>> identify nodes using the benefits of a hierarchical structure, based on 
>> inheritance. 
>>  
>>
>
> As you might guess from my approach to the issue, I've never been much of 
> a fan of node-scoped variables in the first place.  I particularly don't 
> care for them as a means to feed data to classes.  Although that provides 
> for very safe use of node inheritance, it also means that I can adapt very 
> easily to not having node inheritance.
>

Indeed. Honestly I won't miss nodes inheritance too, not anymore.
In fact I don't see any advantage to other, more concise and effective, 
ways to assign variables and classes to nodes.

Given this, and back to the topic of this thread, then, Jason, I would do 
something like:

node 'myweb'  {
   include site
   class{ 'web': }
}

node 'mydb'  {
   include site
   class{ 'db': }
}

and in the site class (and/or its subclasses manage the general baseline 
common to all your systems):
class { 'site':
   class{ 'ntp': }
   class{ 'dns': }
   class{ 'monitoring': }
   class{ 'puppet_agent': }
}

Alternatively, and even better, if you have a way to set a $role  variable 
(either as custom or external fact, or via an ENC, or extracting its value 
using Puppet DSL from the certname of the clients directly in site.pp (so 
setting $role at top scope), you can have a "nodeless setup" and a site.pp 
as simple as

include site
# Call is site, call with with your compay/project name or whatever 

and the in $MODULEPATH/site/manifests/init.pp have your site class with 
common resources and optional addition of role specific ones):

class { 'site':
   class{ 'ntp': }
   class{ 'dns': }
   class{ 'monitoring': }
   class{ 'puppet_agent': }

  if $::role and $::role != '' {  # On Puppet <4 is enough if $::role 
    include "::site::roles::${::role}"
  }
}


Then for each role, have a class like:
class site::roles::db {
 # Resources or classes for this role
}
 
Hope it helped,
my2c

PS: Thanks for your time and your answers John, always appreciated

-- 
You received this message because you are subscribed to the Google Groups 
"Puppet Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to puppet-users+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/puppet-users/d466f2d0-d7be-498d-a892-9a35d115a76b%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to