Is Hiera the right tool for this ?

345 views
Skip to first unread message

Jeff

unread,
Apr 7, 2012, 10:18:55 AM4/7/12
to puppet...@googlegroups.com

Hi puppeteers,

I’m starting from scratch with Puppet 2.7 and I’m trying to avoid some pitfalls from the past using another configuration management tool.  I think most of the issues I had could be solved by Puppet and Hiera but being new to the tool and the approach, Im seeking for advice.

I have a common use case with the configuration of sysctl settings I believe will help me understand if Hiera is the right tool or approach to the problem.   Now the requirements are :

1) All nodes get a set of default settings

2) Based on facts such as function/application, settings are added incrementally

3) A default setting might be overridden for a specific use.

 

The ‘old’ way I used to solve this was through templating and lots if/else statements… but that’s exactly what Im trying to avoid as the knowledge about the infrastructure gets spread everywhere.

 When I found about the Puppet and Augeas combination I thought that was the solution.  I also wanted an ENC and using hiera sound great also.

 So here’s the hiera config :

---

:hierarchy:

    - %{fqdn}

    - %{os}

    - %{role}

    - %{datacenter}

    - common

:backends:

    - yaml

:yaml:

    :datadir: '/etc/puppet/hieradata'

 

The common sysctl are in common.yaml:

classes:

    - sysctl

sysctl_settings:

     net.ipv4.ip_forward:

        value: 0

     kernel.randomize_va_space:

        value: 1

     net.ipv4.conf.all.send_redirects:

        value: 0

 

The more specific and possibly overriding parameters are in role-ap.yaml:

classes:

    - sysctl

 

sysctl_settings:

      vm.swapiness:

             value: 0

      net.ipv4.ip_forward:

             value: 1


The sysctl wrapper module :


class sysctl {

    create_resources( sysctl::config, hiera('sysctl_settings') )

}

define sysctl::config ($value) {

         augeas { "sysctl_${name}":

             context => "/files/etc/sysctl.conf",

             lens    => "sysctl.lns",

             incl    => "/etc/sysctl.conf",

             changes => [ "set ${name} ${value}" ],

         }

    }

 Now the issue is that only the settings found in role-ap.yaml are applied.   It looks like hiera stops at the first array matching in the hierarchy.   Did I got this all wrong?   

 The other issue with this approach is I can’t define a ‘’sysctl_${name}’ resource twice so overriding a parameter doesn’t work either.  How can I get the same result as with capitalization of a File resource for example?

Thanks to all, 

Jeff

unread,
Apr 9, 2012, 8:50:34 AM4/9/12
to puppet...@googlegroups.com
I found a workaround by using distinct array names for default/specific sysctl values and requiring the default class in the role specific class... but I hoped there was a clever way.    Anyone ?


class sysctl::defaults {

    create_resources( sysctl::config::defaults, hiera('sysctl_settings_defaults') )

}

define sysctl::config::defaults ($value) {
         augeas { "sysctl_${name}":
             context => "/files/etc/sysctl.conf",
             lens    => "sysctl.lns",
             incl    => "/etc/sysctl.conf",
             changes => [ "set ${name} ${value}" ],
         }
    }


class sysctl::specific {

    require sysctl::defaults
    create_resources( sysctl::config::specific, hiera('sysctl_settings_specific') )

}


define sysctl::config::specific ($value) {
         augeas { "Sysctl_${name}":

jcbollinger

unread,
Apr 9, 2012, 10:59:15 AM4/9/12
to Puppet Users


On Apr 7, 9:18 am, Jeff <jixe...@hotmail.com> wrote:
> Hi puppeteers,
>
> I’m starting from scratch with Puppet 2.7 and I’m trying to avoid some
> pitfalls from the past using another configuration management tool.  I
> think most of the issues I had could be solved by Puppet and Hiera but
> being new to the tool and the approach, Im seeking for advice.
>
> I have a common use case with the configuration of sysctl settings I
> believe will help me understand if Hiera is the right tool or approach to
> the problem.   Now the requirements are :
>
> 1) All nodes get a set of default settings
>
> 2) Based on facts such as function/application, settings are added
> incrementally
>
> 3) A default setting might be overridden for a specific use.
>
> The ‘old’ way I used to solve this was through templating and lots if/else
> statements… but that’s exactly what Im trying to avoid as the knowledge
> about the infrastructure gets spread everywhere.


Note that with Puppet, templates are processed on the *master* (based
on node facts), so templates do not leak knowledge. Nodes see only
their copy of the resulting file.

That does not make the template solution elegant, but it might be
useful information for you to have.


>  When I found about the Puppet and Augeas combination I thought that was
> the solution.  I also wanted an ENC and using hiera sound great also.

> [...] Now the issue is that only the settings found in role-ap.yaml are applied.
> It looks like hiera stops at the first array matching in the hierarchy.   Did
> I got this all wrong?


The hiera() function performs a priority lookup, stopping at the first
match for the requested key. This is what allows you to override
values defined at low-priority levels of your data hierarchy with
values defined at higher levels. If you want instead to collect all
the values for a key defined at any level of your hierarchy, then use
the hiera_array() or hiera_hash() function instead. There is an
example toward the end of http://puppetlabs.com/blog/first-look-at-installing-and-using-hiera/


>  The other issue with this approach is I can’t define a ‘’sysctl_${name}’
> resource twice so overriding a parameter doesn’t work either.  How can I
> get the same result as with capitalization of a File resource for example?


Puppet uses capitalization of resource type names for a few different
purposes. All of those revolve around referring to resource instances
declared elsewhere, but I'm not sure which you have in mind. If
you're trying to override resource properties then that is better
achieved via Hiera (see my comments above about priority lookup),
especially given that you're using Hiera already.


John

Nan Liu

unread,
Apr 9, 2012, 11:07:13 AM4/9/12
to puppet...@googlegroups.com
On Mon, Apr 9, 2012 at 5:50 AM, Jeff <jix...@hotmail.com> wrote:
> I found a workaround by using distinct array names for default/specific
> sysctl values and requiring the default class in the role specific class...
> but I hoped there was a clever way.    Anyone ?

Try using a hash instead of array and hiera_hash function instead.
hiera_hash will merge each key which seems to be closer to the
behavior you are looking for.

HTH,

Nan

Jeff

unread,
Apr 10, 2012, 10:58:00 AM4/10/12
to puppet...@googlegroups.com

Many thanks to you John and Nan.  Using the hiera_hash function provides the desired behavior and it effectively replaced the need for resource capitalization for my use case.

One last thing Im puzzled with if I may:  A more complex use case where a parameter has to be set based on 2 criterias together on the same hiera level,  lets say 'os' and 'role' (like a sysctl for an app server under rhel4 vs rhel5 ),  how would you solve this ?
 
---
:hierarchy:
    - %{fqdn}
    - %{environnement}
    - %{datacenter}

    - %{os}
    - %{role}
    - common

best regards,

Jeff


On Saturday, April 7, 2012 10:18:55 AM UTC-4, Jeff wrote:

jcbollinger

unread,
Apr 11, 2012, 9:00:44 AM4/11/12
to Puppet Users


On Apr 10, 9:58 am, Jeff <jixe...@hotmail.com> wrote:
> Many thanks to you John and Nan.  Using the hiera_hash function provides
> the desired behavior and it effectively replaced the need for resource
> capitalization for my use case.
>
> One last thing Im puzzled with if I may:  A more complex use case where a
> parameter has to be set based on 2 criterias together on the same hiera
> level,  lets say 'os' and 'role' (like a sysctl for an app server under
> rhel4 vs rhel5 ),  how would you solve this ?
>
> ---
> :hierarchy:
>     - %{fqdn}
>     - %{environnement}
>     - %{datacenter}
>     - %{os}
>     - %{role}
>     - common


I think the %{foo} syntax is just doing a text interpolation, so you
should be able to define a level such as
- %{os}_%{role}

I would try to resist doing so, however, because a simpler hierarchy
will be easier to maintain, and also because of the combinatorial
implications. You might find that you can instead combine separate
pieces of data from your %{os} and %{role} levels inside your
manifests (or templates) to construct the target value.

Do not neglect the possibilities inherent in hiera's support for
complex data types. For example, one of the items in your %{os} data
could be a *table* (as a hash) of possible target values for some
property. Then your %{role} data could specify which key into that
table to use to select the appropriate value for the os/role
combination.


John
Reply all
Reply to author
Forward
0 new messages