[Puppet Users] Re: Puppet 2.7, hiera 1.0 and hiera as an ENC

2012-10-04 Thread Guillem Liarte
John,

Many thanks for your long reply, it is much appreciated. You have assured 
me in teh conclusions and course of action and i am glad that my 
appreciation of teh problem I have was not so far from the reality. 

Thanks again.

Guillem 

On Wednesday, 26 September 2012 16:52:19 UTC+1, Guillem Liarte wrote:

 This is the situation I have:

 All my hosts are the* same OS.*
 All my host are in the* same puppet environment,* so I cannot use 
 %{environment}

 I have a module that sets all the *basic* functionality for the OS, 
 resolution, authentication, security, packages, etc
 I have a module for each application hosted.

 At the moment all the 'data' is in Puppet, mostly in parametrised classes 
 in site.pp.

 What I want to get is a hiera set-up that allows me to use this structure:

 :hierarchy:
   - global # source of application names (classes? modules?) and 
 environments list
   - basic # data for the basic class
   - prod/%{application}/%{hostname}# hostname files for specific 
 data
   - prod/%{application}/%{env} # environmental data for 
 each application (module)
   - prod/%{application}/default # default data for an 
 application
   - nonprod/%{sysclass}/%{hostname}
   - nonprod/%{sysclass}/%{env}
   - nonprod/%{sysclass}/default 
   

 Then to have something like this under the datadir:


 #├── global.yaml
 #├── basic.yaml
 #├── nonprod
 #│   ├── app1
 #│   │   ├── common-integration.yamlAlfresco common 
 integration
 #│   │   ├── continuous-integration.yaml   
 #│   │   ├── dev.yaml
 #│   │   ├── default.yaml
 #│   │   ├── host1.yaml   
 #│   │   ├── host2.yaml
 #│   │   ├── performance.yaml
 #│   │   ├── qa.yaml
 #│   │   ├── test.yaml
 #│   │   └── uat.yaml
 #│   └── app2
 #└── prod
 #├── app1
 #└── app2
 # 
 # etc.

 In global.yaml

 ---
 :classes:
   basic:
   app1:
   app2:
   app3:
   app4:
 :env:
   test:
   dev:
   commonint:
   continuousint:
   dev:
   performance:
   qa:
   test:
   uat:


 in app1 default.yaml:

 ---
 classes:
   app1:

 app1_version:  'latest'



 in app1 dev.yaml:
 ---
 app1_version:  '3.0'

 If I wanted host1 and host2 to be part of dev for app1:


 host1.yaml:
 ---
 classes:
   basic:
   app1:
 env:
   dev:

 maybe in host2 I want to override version too:

 host2.yaml
 ---
 classes:
   basic:
   app1:
 env:
   dev:
 app1_version: '3.1'


 So in short, I would like hiera to be a source of facts, where I can get 
 information that feeds Puppet in order to classify the nodes and to feed 
 the parametrised classes.

 I recently found this blog entry:

 http://garyhetzel.com/2012/04/12/hiera_as_a_puppet_enc

 Gary has been very helpful and I have got an idea of what needs doing. I 
 can query all the data the way I want using the hiera command. Something 
 like these:

 hiera app1_version sysclass=app1 env=dev

 Returns the expected '3.0' and if I query by adding teh host:

 hiera app1_version sysclass=app1 env=dev hostname=host1

 I get 3.1. Cool!


 Example using Gary's approach:

 /opt/puppet-data/nonprod/hieratest/default.yaml 
 ---
 classes: hieratest
 env: hieratest_default

 /opt/puppet-data/nonprod/hieratest/host1.yaml 
 ---
 classes: 
   hieratest:
 env: 'hieratest_performance'


 # hiera env sysclass=hieratest --debug
 DEBUG: Wed Sep 26 16:40:46 +0100 2012: Hiera YAML backend starting
 DEBUG: Wed Sep 26 16:40:46 +0100 2012: Looking up type in YAML backend
 DEBUG: Wed Sep 26 16:40:46 +0100 2012: Looking for data source global
 DEBUG: Wed Sep 26 16:40:46 +0100 2012: Looking for data source basic
 DEBUG: Wed Sep 26 16:40:46 +0100 2012: Looking for data source 
 nonprod/hieratest/default
 DEBUG: Wed Sep 26 16:40:46 +0100 2012: Found env in 
 nonprod/hieratest/default
 hieratest_default

 # hiera type sysclass=hieratest hostname=host1 --debug
 DEBUG: Wed Sep 26 16:40:57 +0100 2012: Hiera YAML backend starting
 DEBUG: Wed Sep 26 16:40:57 +0100 2012: Looking up type in YAML backend
 DEBUG: Wed Sep 26 16:40:57 +0100 2012: Looking for data source global
 DEBUG: Wed Sep 26 16:40:57 +0100 2012: Looking for data source basic
 DEBUG: Wed Sep 26 16:40:57 +0100 2012: Looking for data source 
 nonprod/hieratest/host1
 DEBUG: Wed Sep 26 16:40:57 +0100 2012: Found env in nonprod/hieratest/host1
 hieratest_performance


 But when it comes to use this in Puppet the results are not as I expect, 
 nothing happens, it just does a run no classes are used. I see that the 
 basic class custom facts are loaded, but nothing gets executed, as if the 
 catalogue for host1 would not include it.


 In Puppet  I expect to just have:

 in site.pp:
 node default {}

 And then in each application’s init.pp:

 $env = hiera(env)   this allows me to get the right config  files 
 (with are maintained in a git repo)
 $app1_version = hiera(app1_version)  this allows me to set the right 
 RPM version (from satellite/spacewalk/RHN)

 As per Gary's post, I can use hiera as node terminus, and 

[Puppet Users] Re: Puppet 2.7, hiera 1.0 and hiera as an ENC

2012-10-01 Thread Guillem Liarte
All,

Do I understand I have hit a dead-end? 

On Wednesday, 26 September 2012 16:52:19 UTC+1, Guillem Liarte wrote:

 This is the situation I have:

 All my hosts are the* same OS.*
 All my host are in the* same puppet environment,* so I cannot use 
 %{environment}

 I have a module that sets all the *basic* functionality for the OS, 
 resolution, authentication, security, packages, etc
 I have a module for each application hosted.

 At the moment all the 'data' is in Puppet, mostly in parametrised classes 
 in site.pp.

 What I want to get is a hiera set-up that allows me to use this structure:

 :hierarchy:
   - global # source of application names (classes? modules?) and 
 environments list
   - basic # data for the basic class
   - prod/%{application}/%{hostname}# hostname files for specific 
 data
   - prod/%{application}/%{env} # environmental data for 
 each application (module)
   - prod/%{application}/default # default data for an 
 application
   - nonprod/%{sysclass}/%{hostname}
   - nonprod/%{sysclass}/%{env}
   - nonprod/%{sysclass}/default 
   

 Then to have something like this under the datadir:


 #├── global.yaml
 #├── basic.yaml
 #├── nonprod
 #│   ├── app1
 #│   │   ├── common-integration.yamlAlfresco common 
 integration
 #│   │   ├── continuous-integration.yaml   
 #│   │   ├── dev.yaml
 #│   │   ├── default.yaml
 #│   │   ├── host1.yaml   
 #│   │   ├── host2.yaml
 #│   │   ├── performance.yaml
 #│   │   ├── qa.yaml
 #│   │   ├── test.yaml
 #│   │   └── uat.yaml
 #│   └── app2
 #└── prod
 #├── app1
 #└── app2
 # 
 # etc.

 In global.yaml

 ---
 :classes:
   basic:
   app1:
   app2:
   app3:
   app4:
 :env:
   test:
   dev:
   commonint:
   continuousint:
   dev:
   performance:
   qa:
   test:
   uat:


 in app1 default.yaml:

 ---
 classes:
   app1:

 app1_version:  'latest'



 in app1 dev.yaml:
 ---
 app1_version:  '3.0'

 If I wanted host1 and host2 to be part of dev for app1:


 host1.yaml:
 ---
 classes:
   basic:
   app1:
 env:
   dev:

 maybe in host2 I want to override version too:

 host2.yaml
 ---
 classes:
   basic:
   app1:
 env:
   dev:
 app1_version: '3.1'


 So in short, I would like hiera to be a source of facts, where I can get 
 information that feeds Puppet in order to classify the nodes and to feed 
 the parametrised classes.

 I recently found this blog entry:

 http://garyhetzel.com/2012/04/12/hiera_as_a_puppet_enc

 Gary has been very helpful and I have got an idea of what needs doing. I 
 can query all the data the way I want using the hiera command. Something 
 like these:

 hiera app1_version sysclass=app1 env=dev

 Returns the expected '3.0' and if I query by adding teh host:

 hiera app1_version sysclass=app1 env=dev hostname=host1

 I get 3.1. Cool!


 Example using Gary's approach:

 /opt/puppet-data/nonprod/hieratest/default.yaml 
 ---
 classes: hieratest
 env: hieratest_default

 /opt/puppet-data/nonprod/hieratest/host1.yaml 
 ---
 classes: 
   hieratest:
 env: 'hieratest_performance'


 # hiera env sysclass=hieratest --debug
 DEBUG: Wed Sep 26 16:40:46 +0100 2012: Hiera YAML backend starting
 DEBUG: Wed Sep 26 16:40:46 +0100 2012: Looking up type in YAML backend
 DEBUG: Wed Sep 26 16:40:46 +0100 2012: Looking for data source global
 DEBUG: Wed Sep 26 16:40:46 +0100 2012: Looking for data source basic
 DEBUG: Wed Sep 26 16:40:46 +0100 2012: Looking for data source 
 nonprod/hieratest/default
 DEBUG: Wed Sep 26 16:40:46 +0100 2012: Found env in 
 nonprod/hieratest/default
 hieratest_default

 # hiera type sysclass=hieratest hostname=host1 --debug
 DEBUG: Wed Sep 26 16:40:57 +0100 2012: Hiera YAML backend starting
 DEBUG: Wed Sep 26 16:40:57 +0100 2012: Looking up type in YAML backend
 DEBUG: Wed Sep 26 16:40:57 +0100 2012: Looking for data source global
 DEBUG: Wed Sep 26 16:40:57 +0100 2012: Looking for data source basic
 DEBUG: Wed Sep 26 16:40:57 +0100 2012: Looking for data source 
 nonprod/hieratest/host1
 DEBUG: Wed Sep 26 16:40:57 +0100 2012: Found env in nonprod/hieratest/host1
 hieratest_performance


 But when it comes to use this in Puppet the results are not as I expect, 
 nothing happens, it just does a run no classes are used. I see that the 
 basic class custom facts are loaded, but nothing gets executed, as if the 
 catalogue for host1 would not include it.


 In Puppet  I expect to just have:

 in site.pp:
 node default {}

 And then in each application’s init.pp:

 $env = hiera(env)   this allows me to get the right config  files 
 (with are maintained in a git repo)
 $app1_version = hiera(app1_version)  this allows me to set the right 
 RPM version (from satellite/spacewalk/RHN)

 As per Gary's post, I can use hiera as node terminus, and so it is set in 
 puppet.conf.

 I would like to make emphasis  in this: Gary's hiera as an ENC works, but 
 for a more simple scenario than the one I am proposing, if I only wanted to 
 classify 

[Puppet Users] Re: Puppet 2.7, hiera 1.0 and hiera as an ENC

2012-10-01 Thread jcbollinger


On Wednesday, September 26, 2012 10:52:19 AM UTC-5, Guillem Liarte wrote:

 This is the situation I have:

 All my hosts are the* same OS.*
 All my host are in the* same puppet environment,* so I cannot use 
 %{environment}

 I have a module that sets all the *basic* functionality for the OS, 
 resolution, authentication, security, packages, etc
 I have a module for each application hosted.

 At the moment all the 'data' is in Puppet, mostly in parametrised classes 
 in site.pp.

 What I want to get is a hiera set-up that allows me to use this structure:



I suspect that one of the reasons you are having trouble is that you are 
trying to employ a usage paradigm that is inconsistent with hiera's design 
(more below).
 


 :hierarchy:
   - global # source of application names (classes? modules?) and 
 environments list
   - basic # data for the basic class


There's nothing wrong with those levels.
 

   - prod/%{application}/%{hostname}# hostname files for specific 
 data
   - prod/%{application}/%{env} # environmental data for 
 each application (module)
   - prod/%{application}/default # default data for an 
 application



But there *is* a problem with those.  It may be possible to make it work, 
but it's shaky to use variable hierarchy levels for data *selection*.  
That's what keys are for.  With that said, recent Puppet releases provide 
automatic $calling_module and $calling_class variables, one of which you 
could probably use in place of $application.  As I understand it, that's 
intended to provide (better) support for module-specific data, which might 
be a good way to cast that part of your problem.

 

   - nonprod/%{sysclass}/%{hostname}
   - nonprod/%{sysclass}/%{env}
   - nonprod/%{sysclass}/default



You additionally have a fundamental problem with %{env}.  Hiera will 
attempt to resolve that as a *Puppet* variable, to which the presence of a 
matching key somewhere in the Hiera hierarchy is irrelevant.  Hiera needs 
to know the value to resolve the hierarchy (as you have defined it), and it 
would need, in principle, to resolve the hierarchy before it could look up 
the value in your data store.

What actually happens, I'm sure, is that hiera uses the value of $::env 
that it looks up in Puppet at function entry.  You might be able to work 
around that by setting that variable in Puppet before looking up other 
data, such as by putting

$env = hiera('env')

at top scope near the beginning of your site.pp.



 So in short, I would like hiera to be a source of facts, where I can get 
 information that feeds Puppet in order to classify the nodes and to feed 
 the parametrised classes.



As an aside, throwing parametrized classes into this mix has only downside 
as far as I am concerned, except inasmuch as you may want to use 
parametrized classes that are (unwisely) provided by modules written by 
others.  Since you want to rely on hiera (which is good), it is superior to 
write your classes like this wherever you are in control of module 
interfaces:

class mymodule::class1 {
  $param1 = hiera('mymodule::class1::param1')
  $param2 = hiera('mymodule::class1::param2')
  # or with simpler keys enabled by use of
  # %{calling_module} and/or %{calling_class}
}

There are several advantages, among them that you can encode interclass 
parse-order dependencies via the built-in 'include' function, and that you 
can use hiera's 'hiera_include()' function to assign such classes to nodes.
 


 I recently found this blog entry:

 http://garyhetzel.com/2012/04/12/hiera_as_a_puppet_enc



Gary appears to have done some cool work there, but as you have discovered, 
it's not going to overcome the inherent problem with self-referrential 
data.  It might be possible to work around this by augmenting Gary's hiera 
additions/modifications with a separate pre-lookup of needed extra 
variables, but you're then talking about a distinctly non-trivial effort 
and a substantial branch away from stock hiera.
 

I would like to make emphasis  in this: Gary's hiera as an ENC works, but 
 for a more simple scenario than the one I am proposing, if I only wanted to 
 classify Classes and Hosts, it does work fine. Where I have not been able 
 to succeed is in adding an 'env' layer after the application (classes, 
 organised in modules).



You are classifying based only on hostname, because that's the only data 
you want to consider that actually originates from the node being 
classified.  Everything else is logic and structure of the ENC you are 
trying to build.

The problem is that you are trying to implement a data structure that Hiera 
does not natively support.  You can make it work, but you will need either 
significant changes in hiera, or a different usage mode.  I would suggest 
the latter.

Were I you, I would consider writing a separate, hiera-based ENC instead of 
trying to build all the ENC features you want directly into hiera itself.  
Among other 

Re: [Puppet Users] Re: Puppet 2.7, hiera 1.0 and hiera as an ENC

2012-10-01 Thread Thomas Linkin
Guillem, 

Sorry for the delayed response. Anyway, John is correct about what you're 
trying to do with Hiera. I can say as far as the ENC Gary has written follows 
all the rules of what an ENC 'should do' as per the documentation.

http://docs.puppetlabs.com/guides/external_nodes.html

Keep in mind also, when the ENC is run, the only information it has access to 
is the Facts from the node. The manifests are not compiled until after the ENC 
returns the classes it has determined should be declared. This ENC does it in 
one call to hiera for classes. When this Hiera ENC processes, it never adds the 
discovered parameters and other variables to the current running context. While 
that could achieve what you want, it could also complicate things in unexpected 
ways. So as I said above, when the ENC runs, you only have just the facts from 
the host as your current context.

John's suggestion of a new usage model that aligns better with Hiera's design 
is probably the best answer. That being a case, I would suggest custom facts to 
help you navigate your hiera tree in a more controlled/granular manner. 

-- 
Tom Linkin
Professional Services Engineer
http://puppetlabs.com/
twitter: @trlinkin


On Monday, October 1, 2012 at 10:47 AM, jcbollinger wrote:

 
 
 On Wednesday, September 26, 2012 10:52:19 AM UTC-5, Guillem Liarte wrote:
  This is the situation I have:
  
  All my hosts are the same OS.
  All my host are in the same puppet environment, so I cannot use 
  %{environment}
  
  I have a module that sets all the basic functionality for the OS, 
  resolution, authentication, security, packages, etc
  I have a module for each application hosted.
  
  At the moment all the 'data' is in Puppet, mostly in parametrised classes 
  in site.pp.
  
  What I want to get is a hiera set-up that allows me to use this structure:
 
 
 I suspect that one of the reasons you are having trouble is that you are 
 trying to employ a usage paradigm that is inconsistent with hiera's design 
 (more below).
  
  
  :hierarchy:
- global # source of application names (classes? modules?) and 
  environments list
- basic # data for the basic class
 
 There's nothing wrong with those levels.
  
- prod/%{application}/%{hostname}# hostname files for specific 
  data
- prod/%{application}/%{env} # environmental data for 
  each application (module)
- prod/%{application}/default # default data for an 
  application
 
 
 But there is a problem with those.  It may be possible to make it work, but 
 it's shaky to use variable hierarchy levels for data selection.  That's what 
 keys are for.  With that said, recent Puppet releases provide automatic 
 $calling_module and $calling_class variables, one of which you could probably 
 use in place of $application.  As I understand it, that's intended to provide 
 (better) support for module-specific data, which might be a good way to cast 
 that part of your problem.
 
  
- nonprod/%{sysclass}/%{hostname}
- nonprod/%{sysclass}/%{env}
- nonprod/%{sysclass}/default
 
 
 You additionally have a fundamental problem with %{env}.  Hiera will attempt 
 to resolve that as a Puppet variable, to which the presence of a matching key 
 somewhere in the Hiera hierarchy is irrelevant.  Hiera needs to know the 
 value to resolve the hierarchy (as you have defined it), and it would need, 
 in principle, to resolve the hierarchy before it could look up the value in 
 your data store.
 
 What actually happens, I'm sure, is that hiera uses the value of $::env that 
 it looks up in Puppet at function entry.  You might be able to work around 
 that by setting that variable in Puppet before looking up other data, such as 
 by putting
 
 $env = hiera('env')
 
 at top scope near the beginning of your site.pp.
 
 
  
  So in short, I would like hiera to be a source of facts, where I can get 
  information that feeds Puppet in order to classify the nodes and to feed 
  the parametrised classes.
 
 
 As an aside, throwing parametrized classes into this mix has only downside as 
 far as I am concerned, except inasmuch as you may want to use parametrized 
 classes that are (unwisely) provided by modules written by others.  Since you 
 want to rely on hiera (which is good), it is superior to write your classes 
 like this wherever you are in control of module interfaces:
 
 class mymodule::class1 {
   $param1 = hiera('mymodule::class1::param1')
   $param2 = hiera('mymodule::class1::param2')
   # or with simpler keys enabled by use of
   # %{calling_module} and/or %{calling_class}
 }
 
 There are several advantages, among them that you can encode interclass 
 parse-order dependencies via the built-in 'include' function, and that you 
 can use hiera's 'hiera_include()' function to assign such classes to nodes.
  
  
  I recently found this blog entry:
  
  http://garyhetzel.com/2012/04/12/hiera_as_a_puppet_enc
  
 
 
 Gary appears to have done some cool