5

I'm using the yumrepo built-in type. I can get a basic integration to hiera working

  yumrepo { hiera('yumrepo::name') :
    metadata_expire => hiera('yumrepo::metadata_expire'),
    descr           => hiera('yumrepo::descr'),
    gpgcheck        => hiera('yumrepo::gpgcheck'),
    http_caching    => hiera('yumrepo::http_caching'),
    baseurl         => hiera('yumrepo::baseurl'),
    enabled         => hiera('yumrepo::enabled'),
  }

If I try to remove that definition and instead go for hiera_include('classes'), here's what I've got in the corresponding yaml backend

classes:
 - "yumrepo"

yumrepo::metadata_expire: 0
yumrepo::descr: "custom repository"
yumrepo::gpgcheck: 0
yumrepo::http_caching: none
yumrepo::baseurl: "http://myserver/custom-repo/$basearch"
yumrepo::enabled: 1

I get this error on an agent

Error 400 on SERVER: Could not find class yumrepo

I guess you can't get away from some sort of minimal node declaration w/ hiera and resource types? Maybe hiera_hash is the way to go?

I gave this a shot, but it produces a syntax error

  yumrepo { 'hnav-development':
    hiera_hash('yumrepo')
  }
quickshiftin
  • 2,125
  • 5
  • 27
  • 41
  • Do you understand the different between a module, a class, a node, and a type in puppet? Have you read through http://docs.puppetlabs.com/hiera/1/complete_example.html to see an example of how to use hiera? – sciurus Oct 30 '13 at 19:15
  • Yes, and I don't see any examples of how to declare built-in types in the examples. In general I think it's safe to say most of the documentation on hiera is scant. – quickshiftin Oct 30 '13 at 19:43
  • You don't see any documentation because that's not how you use it. – sciurus Oct 30 '13 at 21:15
  • If you want to demonstrate how to use hiera to declare a built-in resource type or appropriate alternative - answers welcome! – quickshiftin Oct 30 '13 at 21:20
  • I think that what you're specifically asking for isn't possible, and as Shane said, once you think about it doesn't make sense. I've tried to give an example below of how hiera could be used. Sorry if I came of as snippy, I'm just a little tired. – sciurus Oct 30 '13 at 21:43
  • No prob; I appreciate you taking time to offer an answer and help me understand. – quickshiftin Oct 30 '13 at 23:16

4 Answers4

4

I've ended up using create_resources. Essentially it provides the ability to map defined types to nodes with hiera, in much the same way hiera_include does with classes out of the box.

With this setup I can declare any number of file resource types at any level of the hierarchy, plus the configuration is all in hiera datasources.

/etc/hiera.yaml

:hierarchy:
  - defaults
  - "%{environment}"

/var/lib/hiera/defaults.yaml

classes:
  - hiera_file_wrapper
hiera_file:
    hiera-two:
       path: /home/quickshiftin/hiera-two
       ensure: file
       content: 'Hiera two' 

/var/lib/hiera/production.yaml

hiera_file:
    hiera-baby:
       path: /home/quickshiftin/hiera-baby
       ensure: file
       content: 'Hiera baby!

modules/hiera_file_wrapper/manifestes/init.pp

class hiera_file_wrapper()
{
    create_resources(file, hiera_hash('hiera_file'))
}

manifestes/site.pp

hiera_include('classes')
quickshiftin
  • 2,125
  • 5
  • 27
  • 41
  • I ended up generalizing this and making a [mini-language feature](https://github.com/quickshiftin/puppet-hiera-module#hiera_declare_types)! – quickshiftin Nov 02 '13 at 19:29
  • 1
    And finally a [blog post](http://quickshiftin.com/blog/2013/12/declaring-types-through-hiera-data-sources/) that talks more about the philosophy and general approach. – quickshiftin Dec 07 '13 at 19:19
0

Since yumrepo is a resource type, not a class, that won't work.

I'd say put a class in named yumrepo_myreponame and have it declare the yumrepo resource. You can put class parameters in Hiera for that if you need as well, then pass those through to the resource declaration.

For instance, I have a module for turning EPEL on for a server, which can be put in its Hiera classes array to enable it. Its entire content is:

class epel_yumrepo {
  yumrepo { "epel":
    descr          => 'Extra Packages for Enterprise Linux 6 - $basearch',
    enabled        => 1,
    gpgcheck       => 1,
    gpgkey         => 'http://download.fedoraproject.org/pub/epel/RPM-GPG-KEY-EPEL-6',
    mirrorlist     => 'https://mirrors.fedoraproject.org/metalink?repo=epel-6&arch=$basearch',
    failovermethod => "priority",
  }
}
Shane Madden
  • 114,520
  • 13
  • 181
  • 251
  • Cool, I'll set something up. I'm surprised there's not a general set of wrappers for this purpose. A set of modules that passed through parameters for all the corresponding built in types would be nice. – quickshiftin Oct 30 '13 at 19:56
  • @quickshiftin The tricky thing with that is the hiera_include is designed as a way to include classes - it can handle one instance of a class and its parameters. If you were to have a second `yumrepo` you wanted to add in the same way, you'd be out of luck as there's no way to say in Hiera, "these parameters are for one resource, these parameters are for the other". – Shane Madden Oct 30 '13 at 20:01
  • Hmm, that is a bit annoying, but I see what you mean. Ordinarily you're allowed to declare *defined types* as many times as you like, but with this approach, you're limited to one, and thus have to make a wrapper class for each *defined type* declaration. – quickshiftin Oct 30 '13 at 21:33
  • Hiere is a way to separate your data from your code. I don't see how it limits how you declare anything. – sciurus Oct 30 '13 at 21:45
  • Since there's no way to map data from hiera to types like `hiera_include('classes')` for classes, hiera definitely puts some constraints around declarations. All Shane has really done here is moved a type declaration from a node into a module and told it to be declared via hiera. I'm baffled how there's nothing like `hiera_include('types')` for example. – quickshiftin Oct 30 '13 at 23:15
0

Let's assume you had a yum repository named hnav and you needed it to have a different URL based on what version of the OS you're using, 5 or 6.

You configured your hierarchy in /etc/puppet/hiera.yaml like

:hierarchy:
- "%{::operatingsystemmajrelease}"
- common

So that hiera will first look for a yaml file named after the OS version, 5.yaml or 6.yaml. If it doesn't find a value there, it will look in common.yaml.

You wrote a parametrized class so that hiera could automatically supply the url.

modules/hnav/manifests.init.pp

class hnav ( $url ) {
  yumrepo { 'hnav':
    enabled => true,
    baseurl => $url
  }
}

If for some reason you didn't like parametrized classes, you could have written the above as

class hnav {
  yumrepo { 'hnav':
    enabled => true,
    baseurl => hiera('hnav::url')
  }
}

Then your configured the classes you wanted applied on all your nodes

common.yaml

classes:
  - hnav

And you set the values for the URL

5.yaml

hnav::url: http://example.com.yum/5/

6.yaml

hnav::url: http://example.com.yum/6/

This is a really artificial example, but maybe it will help you understand where hiera is used.

sciurus
  • 12,678
  • 2
  • 31
  • 49
  • I realize how this example works, but it doesn't deal with the issue of wanting to declare the `yumrepo` type several times for a given node. What if I wanted another repo in *common.yaml*. I'd need to declare another class. Hiera has [generic support for class declarations](http://docs.puppetlabs.com/hiera/1/puppet.html#assigning-classes-to-nodes-with-hiera-hierainclude), but nothing I can see for *defined type* declarations. Basically you're just moving configuration from node definitions to module definitions, but not to where you'd like it to be, namely *in the yaml*. – quickshiftin Oct 30 '13 at 23:32
0

I built a hiera_manifest functionality at my job. Essentially it allows you to call modules, classes and parameters and defined types all via hiera yaml.

I just put it up on Github to share: https://github.com/mlbam/hiera_manifest

This has slight advantages in that parameters are also put in place at the time of invocation of the module, class or type.

One thing to note is the difference in some syntax for resource definitions when using metaparameters. Also, when troubleshooting, the errors stick to the manifest sometimes and you don't get a proper error message for the module that throws the error.

Ben
  • 9
  • 1
  • I was going to move forward with calling things through the yaml until I realized the need for [composition in puppet](https://quickshiftin.com/blog/2014/01/composition-in-puppet/). Also remember it feeling like duplicated yaml vs class instantiations. Thus I moved my code all back over to puppet and kept the yaml pretty basic in the end. Does your system support composition through yaml? Will look at your library tho, thx for sharing! – quickshiftin Sep 21 '14 at 08:20