Hiera, default site.pp and error could not find class - puppet

I have a server who was running puppet and hiera and, for the moment, 1 client.
I want to manage all my nodes with hiera config files so I only put this in /etc/puppet/manifests/site.pp :
hiera_include(classes, '')
In my file /etc/puppet/hieradata/common :
---
classes:
- "common_test"
- fw_test
- zabbix::agent
zabbix::agent:zabbix_version : '2.2'
zabbix::agent:server: 192.168.1.1
zabbix::agent:serveractive: '192.168.1.1'
zabbix::agent:hostname: 'Test_puppet'
zabbix::agent:manage_firewall: true
With this configuration my parameters (192.168.1.1, true, Test_puppet, etc.) are not set on my client.
Second question, when I add zabbix::userparameters in my class list I have this error Could not find class zabbix::userparameters for...
But this class exist (I use this package https://forge.puppetlabs.com/wdijkerman/zabbix)
I take this example but it's also does'nt work with others classes for the parameters error.
Best regards.

Your parameter keys are incorrect. For example, this ...
zabbix::agent:zabbix_version : '2.2'
... should instead be ...
zabbix::agent::zabbix_version: '2.2'
. The main issue is one too few colons between zabbix::agent and zabbix_version. I don't think whitespace between the key and trailing colon matters, but it's more conventional to not have any.
As for zabbix::userparameters, it is a (defined) resource type, not a class. You cannot include it (or hiera_include() it).

Related

Having some trouble using module hiera in puppet

I am having some trouble using module hiera data.
module: /etc/puppetlabs/code/environments/production/modules/usehiera
tree structure:
usehiera
usehiera/hiera.yaml
usehiera/data
usehiera/data/common.yaml
usehiera/manifests
usehiera/manifests/init.pp
hiera.yaml:
---
version: 5
defaults:
datadir: data
data_hash: yaml_data
hierarchy:
- name: 'common'
- path: 'common.yaml'
data/common.yaml:
---
usehiera::apples: 'this is some data'
manifests/init.pp:
class usehiera{
file{'/tmp/hiera_lookup.txt':
ensure => present,
#content => hiera('oranges') #this works with global hiera
content => $apples
}
}
As you can see I seem to have the global hiera working with "hiera('oranges')" when I run this module on my node. When I try to use the module hiera data the puppet run finishes successfully but hiera_lookup.txt is just empty.
Steps I have taken to troubleshoot:
restart puppetserver after hiera changes
try using $usehira::apples
try using hiera('apples')
moving my hiera.yaml inside data/
using lookup with --explain doesnt really give me anything useful, just says lookup() not found
Can anyone help me out? I have been stuck with this for a decent amount of time and not sure what the issue could be.
As #MattSchuchard pointed out in comments, your hiera.yaml is inappropriately formed. The documentation contains examples.
But a bigger issue seems to be incorrect expectations. Evidently, you assume that ordinary class variable $usehiera::apples will automatically take the value associated with the corresponding key in the module-level hiera data, but that simply is not the case. Hiera data -- whether global, environment-level, or module-level -- is automatically bound to class parameters, but not to other class variables.
You can set ordinary class variables from hiera data via explicit lookup:
# the hiera() function is deprecated; use lookup():
$apples = lookup('usehiera::apples')
Alternatively, you can make $apples a class parameter:
class usehiera(String $apples) {
file{'/tmp/hiera_lookup.txt':
ensure => 'present',
content => $apples,
}
}
Note well that if you make it a parameter then its value can also be customized via a resource-like class declaration, which takes precedence over your Hiera data.
Note also that the difference between global, per-environment, and module-specific Hiera data is just scope and precedence, not functionality.

Puppet: Class Ordering / Containment - always wrong order

I read a lot about ordering puppet classes with containment (iam using Puppet 6). But it still does not work for me in one case. Maybe my english is not good enough and i miss something. Maybe somebody know what iam doing wrong.
I have a profile to installing a puppetserver (profile::puppetserver). This profile has three sub-classes which I contain within the profile::puppetserver
class profile::puppetserver(
) {
contain profile::puppetserver::install
contain profile::puppetserver::config
contain profile::puppetserver::firewall
}
That works fine for me. Now I want to expand this profile and install PuppetDB. For this, i use the puppetdb module from puppet forge:
So what i do is add profile::puppetserver::puppetdb and the contain to the profile::puppetserver
class profile::puppetserver::puppetdb(
) {
# Configure puppetdb and its underlying database
class { 'puppetdb': }
# Configure the Puppet master to use puppetdb
class { 'puppetdb::master::config': }
}
When i provision my puppetserver first and add the profile::puppetserver::puppetdb after it, puppetdb installs and everything works fine.
If I add it directly with contain, and provisioning everything at once, it crashes. It's because the puppetdb module is installed randomly during my master server installs (and also the postgresql server and so on). That ends in my puppetserver is not running and my puppetdb generate no local ssl certificates and the service doesn't comes up.
What i try first:
I installed the puppetdb Package in my profile::puppetserver::puppetdb directly and use the required flag. It works when i provision all at once.
class profile::puppetserver::puppetdb (
) {
Package { 'puppetdb':
ensure => installed,
require => Class['profile::puppetserver::config']
}
}
So i think i could do the same in the code above:
class profile::puppetserver::puppetdb(
) {
# Configure puppetdb and its underlying database
class { 'puppetdb':
require => Class['profile::puppetserver::config']
}
# Configure the Puppet master to use puppetdb
class { 'puppetdb::master::config':
require => Class['profile::puppetserver::config']
}
}
But this does not work...
So i read about puppet class containment and ordering by chains. So i did this in my profile::puppetserver
class profile::puppetserver(
) {
contain profile::puppetserver::install
contain profile::puppetserver::config
contain profile::puppetserver::firewall
contain profile::puppetserver::puppetdb
Class['profile::puppetserver::install'] ->
Class['profile::puppetserver::config'] ->
Class['profile::puppetserver::firewall'] ->
Class['profile::puppetserver::puppetdb']
}
But it still does not have any effect... he still starts to install postgresql and the puppetdb package during my "puppetserver provisioning" in the install, config, firewall steps.
How i must write the ordering, that all things from the puppetdb module, which i call in profile::puppetserver::puppetdb, only starts when the rest of the provisioning steps are finished?
I really don't understand it. I think maybe it haves something to do with the fact, that i declare classes from the puppetdb module inside of profile::puppetserver::puppetdb and not the directly Resource Type. Because when i use the Package Resource Type with the Require Flag, it seems to work. But i really don't know how to handle this. I think there must be a way or?
I think maybe it haves something to do with the fact, that i declare
classes from the puppetdb module inside of
profile::puppetserver::puppetdb and not the directly Resource Type.
Because when i use the Package Resource Type with the Require Flag, it
seems to work.
Exactly so.
Resources are ordered with the class or defined-type instance that directly declares them, as well as according to ordering parameters and instructions applying to them directly.
Because classes can be declared multiple times, in different places, ordering is more complicated for them. Resource-like class declarations such as you demonstrate (and which you really ought to avoid as much as possible) do not imply any particular ordering of the declared class. Neither do declarations via the include function.
Class declarations via the require function place a single-ended ordering constraint on the declared class relative to the declaring class or defined type, and declarations via the contain function place a double-ended ordering constraint similar to that applying to all resource declarations. The chaining arrows and ordering metaparameters can place additional ordering constraints on classes.
But i really dont know how to handle this. I think there must be a way or?
Your last example shows a viable way to enforce ordering at the level of profile::puppetserver, but its effectiveness is contingent on each of its contained classes taking the same approach for any classes they themselves declare, at least where those third-level classes must be constrained by the order of the second-level classes. This appears to be where you are falling down.
Note also that although there is definitely a need to order some things relative to some others, it is not necessary or much useful to try to enforce an explicit total order over all resources. Work with the lightest hand possible, placing only those ordering constraints that serve a good purpose.

Puppet: Declaring a class with inheritance

I currently have two classes that I created within /etc/puppet/modules/params/manifests/init.pp
class modulename ($variable_name = 'Any string') inherits modulename::params{
file { '/tmp/mytoplevelclass.sh' :
mode => '644',
ensure => 'present',
content => $variable_name
}
}
class modulename::params{
}
However, I am having an issue declaring these classes in /etc/puppet/manifests/site.pp. Currently, I have it written as
node default { #client
class { 'modulename':}
class { 'modulename::params':}
}
I know that this is incorrect because when I run puppet agent -t on the client I get an error stating
Could not find declared class modulename at /etc/puppet/manifests/site.pp
I have tried several different configurations and still am unsure on what to do.
Puppet determines the file in which it expects to find a class's definition based on the class's fully-qualified name. The docs go into it in some detail; in particular, you should review the Module Fundamentals. (I am guessing that you are on Puppet 3, but the details I am about to discuss are unchanged in Puppet 4.)
Supposing that /etc/puppet/modules is a directory in your modulepath, it is a fine place to install (or write) your modulename module, as indeed you indicate you are doing. If it is not in your module path, then you'll want either to move your module to a directory in the module path, or to add that directory to the module path. I assume that you will resolve any problem of this sort via the latter alternative, so that /etc/puppet/modules/modulename is a valid module directory.
Now, class 'modulename' is a bit special in that its name is also a module name; as such, it should be defined in /etc/puppet/modules/modulename/manifests/init.pp. Class modulename::params, on the other hand, should follow the normal pattern, being defined in /etc/puppet/modules/modulename/manifests/params.pp. I anticipate that Puppet will find the definitions if you put the definitions in the correct files.
Bonus advice:
Use include-like class declarations in your node blocks, not resource-like declarations
Your node blocks probably should not declare modulename::params at all

puppet use hiera with module

I am going to use puppet bind module from
https://github.com/thias/puppet-bind
any idea how I can use hiera in yaml format with this?
I have tried using this in Hiera, but it does not pass the values to the module.
---
classes:
- 'bind::server'
profile::bind::conf:
'/etc/named.conf':
zones:
'example.com': ['type master', 'file ]
any suggestions?
The parameters cannot be bound to the module's classes automatically - zones are created through a define.
Creating values for define instances in Hiera is a two-step process.
Create the data. Your's is fine, but the key is misleading.
e.g.
bind_server_confs:
'/etc/named.conf':
zones:
'example.com': ['type master', 'file ]
Create resources from the hash using the create_resources function.
like
create_resources('bind::server::conf', hiera('bind_server_confs'), {})
The default result of {} will (correctly) lead to no resources being created.

puppet include and variable scope

Can someone explain to me why would this work :
node 'puppetagent'{
$my_role="proxmoxnode"
include role_proxmoxnode
}
class role_proxmoxnode {
include sshdconf
}
And this won't :
node 'puppetagent'{
include role_proxmoxnode
}
class role_proxmoxnode {
$my_role="proxmoxnode"
include sshdconf
}
By "Work" I mean that the sshd_config.erb file set by sshdconf module will find the $my_role="proxmoxnode" as expected. By "won't work", I mean the template complaining with "Could not find value for 'my_role'"
I use puppet 3.0.
I followed the doc in http://projects.puppetlabs.com/projects/1/wiki/Infrastructure_Design_Guidelines about roles.
Thanks
In Puppet 3.0. unqualified variables are looked up in 4 places:
Local scope
Inherited from a base class
Node-level
Top scope
Local scope, by the way, would apply to variables defined in the class, not in classes which simply include it.
So, in your first example, we go looking:
Is it local? No.
Is it in a base class? No.
Is it in the node? yes. We stop.
In the second example...
Is it local? No.
Is it in a base class? No.
Is it in the node? No.
Is it in top scope? No. Fail.
Clear?

Resources