On Wednesday, March 11, 2015 at 4:35:36 PM UTC, Bostjan Skufca wrote:
>
>
>
>> Something like this seems like I'm telling a module *how* to look up my 
>> own data, rather than passing the right data to the module:
>>
>>
>> class resolv (
>>   $dns_servers_key_name = 'dns_servers',
>>   $dns_servers_key_merge = false,
>> ) {
>>   if ($dns_servers_key_merge) {
>>     $dns_servers = hiera_array($dns_servers_key_name)
>>   } else {
>>     $dns_servers = hiera($dns_servers_key_name)
>>   }
>> }
>>
>> class { 'resolv': dns_servers_key_merge => true }
>>
>>
>> I'd also have to code it to selectively use Hiera or not (some people 
>> don't) and that would get even worse.  The second example of module design 
>> may be super awesomely flexible in terms of how I can structure my Hiera 
>> data, but it doesn't fit the direction the community is moving in terms of 
>> module design.
>>
>
>
> This is almost what I am looking for. I have an alternate approach: what 
> if merging vs nonmerging is decided based on hiera key?
>
>

That is my approach, that class would do an implicit Hiera lookup for those 
class parameters, I just illustrated the point with a resource-like 
declaration as an example. While the above method would work, I don't think 
I've made my point about not putting this personalised logic in the 
"resolv" module itself. The above example is not so good. Gary Larizza 
explains it very well here if you haven't seen it 
(https://www.youtube.com/watch?v=v9LB-NX4_KQ). That video should answer 
your questions in your second reply to me too, BTW.

The above code example is a bad idea for these reasons:

- the resolv module is tightly coupled to the data, it's in control of how 
it should look up data, rather than just be *given* data
- you won't be able to replace that resolv module with the super awesome 
puppetlabs_resolv module because of your custom way of handling data
- it makes a *very* bad assumption that everyone uses Hiera, it is not 
compatible for people who use ENCs that supply all class parameters for 
example
- there's a higher barrier to entry on understanding the module, some 
people would have to read the body of the resolv module code to figure out 
what's going on (or there would be a long README)
- it's more complicated to test because the range of data it can take is 
more complicated

Now expand on my first example:

********************
class puppetlabs_resolv($dns_servers) {
  file { '/etc/resolv.conf': content => template(...) }
}

class profile::dns_base {
  #lookup my DNS data from Hiera
  $hiera_dns_server_array = hiera_array('dns::server')
  #and add a global DNS server I have
  $common_dns_server = '127.0.0.1'
  class { 'puppetlabs_resolv':
    dns_servers => [ $hiera_dns_server_array, $common_dns_server ]
  }
}

class profile::dns_special {
   #don't do a hiera lookup, DNS here is special
   $special_dns = '10.1.1.1'
   class { 'puppetlabs_resolv':
    dns_servers => [ $special_dns ]
  }
}

node dc1 { include profile::dns }
node dc1_special { include profile::dns_special }
********************

The puppetlabs_resolv module I downloaded from GitHub does one thing well, 
resolv.conf, in a simple and easily understood manner, and it comes with 
Rspec tests, so I don't have to reinvent the wheel.

All of my business logic about how I get IP addresses into that resolv 
module is in my profile::dns* classes. These are *my* profile classes, I 
can do whatever crazy Hiera lookups and string manipulation I want/need to 
get the data into a format that puppetlabs_resolv takes. In other words my 
profiles are the "glue" between my data and the "building block" 
puppetlabs_resolv module. At any time I can replace puppetlabs_resolv with 
lukebigum_resolv (which is obviously better) with a few tweaks to my 
profiles. If I replace my data backend or get rid of Hiera entirely, my 
profile might have to be adjusted but I don't have to stop using that 
awesome lukebigum_resolv I downloaded.

Why the use of a second profile, profile::dns_special? It takes complexity 
out of Hiera. I don't need a complicated Hierarchy when I've got profiles, 
and I rarely need inheritance at all. I've got my "tpl_%{::domain}" which 
is where my profile::dns looks up data from, and anything that's special is 
actually a different implementation of how I usually do DNS, so it gets 
it's own profile, hence profile::dns_special. It is better to handle these 
exceptions in Puppet code because it's an *actual* language, rather than 
trying to model something complex into Hiera which is just a key-value 
store.

Your Hiera example where you have tpl_dc1.yaml and tpl_dc1-special.yaml is 
going to bite you. Your joke about mimicking node inheritance functionality 
in Hiera worries me a little, because it reminds me of some of my 
colleagues. Just because it can be modelled in Hiera, doesn't mean it 
should be. To give you an example, at my work place we can build an entire 
platform where each node's Hiera file looks like this:

---
ip_address_fourth_octet: 10

And the rest is abstracted, inherited and hidden away. In some ways it's 
really awesome, but it is also very hard to debug, and extraordinarily hard 
to understand. I once spent 2 hours tracing a string in a configuration 
file through too many Hiera files each with over a dozen levels of 
dictionary/hash depth, about 7 create_resource() calls, several exported 
resources and luckily only 3-4 recursive Hiera lookups. I was not happy by 
the end of that. Not long after my team lead forced us to re-read the Roles 
and Profiles design pattern and to watch that video ;-)

My recommendation to you is to seriously look at why you're relying on 
inheritance and merging so much, I think you could simplify a lot more. If 
you post a more relevant example and your Hierarchy, I'd be happy to 
discuss.

-Luke

-- 
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/9b37aec0-a457-4023-8f2c-d4cfee4f3220%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to