[Puppet Users] Re: Resource chaining is not being honored

2018-03-09 Thread Johnathan Komara
I appreciate you taking the time to review my post and give such a thorough 
answer.

Thank you,

Johnathan

On Friday, March 9, 2018 at 9:52:19 AM UTC-5, jcbollinger wrote:
>
>
>
> On Thursday, March 8, 2018 at 4:53:27 PM UTC-6, Johnathan Komara wrote:
>  
>
>> 'profile::a' should be applied to every server and 'profile::b' is only 
>> being applied to a few servers. My understanding of resource chaining is 
>> that I can alter the order in which the classes are ran. I need "b" to run 
>> first so that I can key off of "defined(File['/etc/test/txt']).
>>
>
>
> No, you don't, and you shouldn't.  You should not use the defined() 
> function at all, in fact, because it produces evaluation-order 
> dependencies, which is exactly what you are dealing with.  You will find 
> considerable discussion of this topic in the archives of this group, 
> including several previous assertions on my part that defined() is evil.
>
> Additionally, you are conflating two different orderings: order of 
> manifest *evaluation* on the master and order of catalog *application* on 
> the target node.  Resource relationships, whether established via the chain 
> operators or via the appropriate resource metaparameters,affect only the 
> latter, whereas defined(), being evaluated during catalog building, is 
> affected only by the former.
>  
>
>>
>> I have tried multiple approaches and I cannot get this to work.
>>
>
>
> I'm not at all surprised, since even if you are determined to use 
> defined() despite my advice, you're trying to use the wrong tool for the 
> job of getting the evaluation order you need to make it work.  Evaluation 
> order depends primarily on the contents and lexical order of your 
> manifests.  It is extremely difficult to predict, and if you have caching 
> enabled in the relevant environment then you're pretty much toast.
>
>  
>
>> The only way that it works is if I explicitly include 'profile::b' before 
>> 'profile::a' in base. 
>>
>> class profile::base {
>>   include 'modules'
>>   include '::profile::b'
>>   include '::profile::a'
>> }
>>
>> Or if I remove 'profile::a' from base and include them both in the role.
>>
>> class role::test_server inherits ::role {
>>   include '::profile::b'
>>   include '::profile::a'
>> }
>>
>>
> As I said, the contents and lexical order of your manifests.  But even 
> that may not be reliable.  Classes can be included multiple times, from 
> multiple locations, and if you have another location where you include 
> ::profile::a before or without including ::profile::b, then your result 
> will depend which declaration of ::profile::a is evaluated first.
>  
>
>>
>> I have alternatives. I can set values in hiera to key off of or push out 
>> custom facts.
>>
>
>
> And that is what you indeed should do instead.  There might be room for an 
> accompanying refactoring of your manifest set to go along with it and make 
> things smoother, but you'll need to determine that for yourself.
>
> Moreover, you might not need to add anything in the first place.  You 
> already have logic some place to determine whether to assign 
> role::test_server to your nodes.  It seems that's the same thing you want 
> to rely on here.
>
>  
>
>> Custom facts will not be there on the first run which is probably ok. I 
>> think we would run into a few issues here and there but I could make it 
>> work.
>>
>
>
> Custom facts could work too, but it is best for the target configuration 
> of your nodes to be determined by their identities and invariant 
> characteristics, based on centrally-maintained manifests and data.
>
>  
>
>> Everything I have read says that chaining the resource should enforce the 
>> order but I am obviously missing something. Can someone see what I am doing 
>> wrong or explain why this will not work?
>>
>
>
> In addition to what I've already said, the fact that you're using class 
> inheritance has bad code smell, and in practice it contributes to your 
> problem.
>
> Class inheritance is an ancient feature of the language that was 
> originally intended to provide for overriding the parameters of resources 
> declared by the parent class.  It still works for that, but Puppet has 
> other mechanisms for that purpose, and for avoiding the need for overrides 
> in the first place, and nowadays those are stylistically preferred.  Class 
> inheritance also has the side effect of causing the parent class to be 
> evaluated before the child class, which is what makes the params class 
> pattern work, and that pattern is the only widely accepted use for class 
> inheritance in modern Puppet.
>
> In OO-speak, prefer composition over inheritance. Very much more so in 
> Puppet DSL -- which looks a lot more like an OO language than it really is 
> -- than in general-purpose OO programming languages, such Java or C++.
>
>
> John
>
>

-- 
You received this message because you are subscribed to the Google Groups 
"Puppet Users" group.
To unsubscribe from this group and stop 

[Puppet Users] Re: Resource chaining is not being honored

2018-03-09 Thread jcbollinger


On Thursday, March 8, 2018 at 4:53:27 PM UTC-6, Johnathan Komara wrote:
 

> 'profile::a' should be applied to every server and 'profile::b' is only 
> being applied to a few servers. My understanding of resource chaining is 
> that I can alter the order in which the classes are ran. I need "b" to run 
> first so that I can key off of "defined(File['/etc/test/txt']).
>


No, you don't, and you shouldn't.  You should not use the defined() 
function at all, in fact, because it produces evaluation-order 
dependencies, which is exactly what you are dealing with.  You will find 
considerable discussion of this topic in the archives of this group, 
including several previous assertions on my part that defined() is evil.

Additionally, you are conflating two different orderings: order of manifest 
*evaluation* on the master and order of catalog *application* on the target 
node.  Resource relationships, whether established via the chain operators 
or via the appropriate resource metaparameters,affect only the latter, 
whereas defined(), being evaluated during catalog building, is affected 
only by the former.
 

>
> I have tried multiple approaches and I cannot get this to work.
>


I'm not at all surprised, since even if you are determined to use defined() 
despite my advice, you're trying to use the wrong tool for the job of 
getting the evaluation order you need to make it work.  Evaluation order 
depends primarily on the contents and lexical order of your manifests.  It 
is extremely difficult to predict, and if you have caching enabled in the 
relevant environment then you're pretty much toast.

 

> The only way that it works is if I explicitly include 'profile::b' before 
> 'profile::a' in base. 
>
> class profile::base {
>   include 'modules'
>   include '::profile::b'
>   include '::profile::a'
> }
>
> Or if I remove 'profile::a' from base and include them both in the role.
>
> class role::test_server inherits ::role {
>   include '::profile::b'
>   include '::profile::a'
> }
>
>
As I said, the contents and lexical order of your manifests.  But even that 
may not be reliable.  Classes can be included multiple times, from multiple 
locations, and if you have another location where you include ::profile::a 
before or without including ::profile::b, then your result will depend 
which declaration of ::profile::a is evaluated first.
 

>
> I have alternatives. I can set values in hiera to key off of or push out 
> custom facts.
>


And that is what you indeed should do instead.  There might be room for an 
accompanying refactoring of your manifest set to go along with it and make 
things smoother, but you'll need to determine that for yourself.

Moreover, you might not need to add anything in the first place.  You 
already have logic some place to determine whether to assign 
role::test_server to your nodes.  It seems that's the same thing you want 
to rely on here.

 

> Custom facts will not be there on the first run which is probably ok. I 
> think we would run into a few issues here and there but I could make it 
> work.
>


Custom facts could work too, but it is best for the target configuration of 
your nodes to be determined by their identities and invariant 
characteristics, based on centrally-maintained manifests and data.

 

> Everything I have read says that chaining the resource should enforce the 
> order but I am obviously missing something. Can someone see what I am doing 
> wrong or explain why this will not work?
>


In addition to what I've already said, the fact that you're using class 
inheritance has bad code smell, and in practice it contributes to your 
problem.

Class inheritance is an ancient feature of the language that was originally 
intended to provide for overriding the parameters of resources declared by 
the parent class.  It still works for that, but Puppet has other mechanisms 
for that purpose, and for avoiding the need for overrides in the first 
place, and nowadays those are stylistically preferred.  Class inheritance 
also has the side effect of causing the parent class to be evaluated before 
the child class, which is what makes the params class pattern work, and 
that pattern is the only widely accepted use for class inheritance in 
modern Puppet.

In OO-speak, prefer composition over inheritance. Very much more so in 
Puppet DSL -- which looks a lot more like an OO language than it really is 
-- than in general-purpose OO programming languages, such Java or C++.


John

-- 
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/1d983827-fcc5-4eeb-899e-2cf2944191c0%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.