On Wednesday, October 18, 2017 at 6:38:51 PM UTC-5, Johan Fleury wrote:
>
> Le 17/10/2017 à 08:59, jcbollinger a écrit : 
> > Nothing has changed with `ensure_resource()`.  The problem is not its 
> > implementation details, but rather the nature of the usage modes the 
> > function is *designed* to support.  The whole idea of it is flawed.  We 
> can 
> > reprise that discussion if you like, but you already have this very 
> thread 
> > and others to which it links from which you can review some of the 
> > discussions that we have had before. 
> > 
>
> What is the problem with ensure_resource? 



So we'll have the reprise, then.

The job of ensure_resource() is to declare a resource in the event that it 
is not declared.  This is primarily meant help address of module 
compatibility concerns.  That sounds just peachy, but it presents both 
conceptual and practical problems.

On the practical side,

   - the function doesn't do quite what you would expect.  All other 
   considerations aside, you would like it to declare the specified resource 
   if otherwise it would not have been declared, but what the function 
   actually does is declare the resource if it has not been declared *yet* 
   when the function is evaluated.  Evaluation-order dependencies such as that 
   produce all kinds of trouble, and in particular,
   - if another declaration of the same resource is evaluated after the 
   ensure_resource() call, then catalog building will fail with a duplicate 
   resource declaration -- the very thing that using ensure_resource() was 
   supposed to avoid.  In practice, then, ensure_resource() is reliable 
   only if it is used consistently on a per-resource basis.  Also,
   - even if all declarations of a given resource were made via 
   ensure_resource(), if in fact there is more than one then there is 
   significant risk that the resource attributes they specify are 
   inconsistent.  This is the very thing that Puppet is designed to avoid by 
   forbidding duplicate resource declarations in the first place, and it can 
   produce the result that the target machine is silently configured 
   differently than you expect.  As an extreme case, consider conflicting  
   ensure_resource() calls for some resource -- a Package, say -- in which 
   one specifies ensure => 'present' and the other specifies ensure => 
   'absent'.  Whichever happens to be evaluated first will win, foiling the 
   intent of the other.
   - All of that is exacerbated by the fact that Puppet manifest evaluation 
   order is difficult to predict, and somewhat chaotic.  That is, small 
   manifest changes in one place can produce widespread evaluation-order 
   changes across the manifest set.  As a result, your 
ensure_resource()-dependent 
   manifest set that works today may break tomorrow when some unrelated change 
   is committed, or may not work for the new machine you're about to add that 
   has a different configuration from any previous one.
   - I am also inclined to suspect, though I have not seen or worked out 
   the details, that evaluation-order dependencies are prone to play poorly 
   with Puppet's environment caching.

On the conceptual side, the mere existence of ensure_resource() and 
ensure_resources() influences manifest writers away from best practices.  
It's like a creepy guy in a panel van rolling up next to impressionable 
young Puppeteers and offering them candy.  Or "candy".

The best solution for avoiding duplicate resource declarations is to ensure 
that every resource is the responsibility of exactly one class (though 
classes may be responsible for multiple resources).  That naturally avoids 
any possibility of duplicate declarations via classes' singleton nature, 
while nevertheless allowing the requirement for that resource, and perhaps 
related ones, to be expressed independently at multiple points in the 
manifest set, in the form of include-like class declarations.  Furthermore, 
if there are conflicting requirements for the resource then those will tend 
to come quickly to developers attention, and site data can be DRYer.  But 
doing this properly is more work than just writing resource declarations as 
ensure_resource() calls, and ensure_resource() makes the immediate pain go 
away often enough to be tempting.

Oh, and note that almost every word of that applies equally to wrapping 
ordinary resource declarations in `if !defined()` checks.  `defined()` is 
evil, too, as I have previously said on more than one occasion.


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/fc044e1c-c6ea-4036-97f9-f30892f94a11%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to