Parameter mapping with Hiera - puppet

Is it possible to map hiera parameter to another one?
For example, if in hiera there is already a parameter "person::shoe::size" , and puppet module "other_module" needs to lookup parameter like this: hiera(person_shoe_size).
Is it possible to tell hiera that parameter "person_shoe_size" is the same thing as "person::shoe::size", and that hiera(person_shoe_size) should actually be mapped to hiera(person::shoe::size)?

Yes, you can do a hiera lookup inside of your value.
person::shoe::size: "7"
person_shoe_size: "%{hiera('person::shoe::size')}"
Looking up either would return 7. You can also do something like this:
hostname: "cool-hostname"
module::fully_qualified_name: "%{hiera('hostname')}.domain.tld"
Here, the fully_qualified_name parameter will have a value of cool-hostname.domain-tld.

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.

In Chef how can you pass attributes with "include_recipe"?

I need to call a recipe and pass it specific attribute data, like:
include_recipe [nginx::passenger['my_attributeA' => 'foobar' , 'my_attributeB' => 'foofii']
i.e. in my wrapper, I have to pass data to a called cookbook.
Thanks
Node attributes in chef are global variables you should do this by setting them in the attributes file:
my_cookbook/attributes/default.rb:
default['my_attributeA'] = 'foobar'
default['my_attributeB'] = 'foofii'
my_cookbook/recipe/default.rb:
include_recipe "nginx::passenger"
my_cookbook/metadata.rb:
name "my_coobook"
version "1.2.3"
depends "nginx"
Note, gnerally you'd be setting node attributes like default['nginx']['some_nginx_cookbook_attribute'] in your wrapper to control the nginx cookbook, you probably wouldn't be setting something arbitrary like default['my_attributeA'].
there is no need to pass an argument for attribute assignment; rather, you will need to overload the attribute before including the desired recipe.
the attributes set in the dependent cookbooks before including other dependee cookbook, will be merged.
if the attribute precedence levels are the same, then that data is merged. If the attribute value precedence levels in an array are different, then that data is replaced. For all other value types (such as strings, integers, etc.), that data is replaced.

How to access a value in an hiera hash directly with puppet lookup?

Let's say there is an hiera hash:
foo::bar:
key1: 'value1'
key2: 'value2'
Is there any possibility to lookup the value of key1 directly with the lookup function?
I thought of something like:
class myclass (
String $value1 = lookup('foo::bar::key1'),
) {
...
}
The only way I could solve this, is to lookup the Hash and acces the value later with hash['key1'], but maybe there is a more clean way to do this.
Unfortunately, there isn't a way to do this in Puppet using just lookup.
Fundamentally, lookup works by looking up Hiera keys, which are unrelated to hash keys. A Hiera key of the form foo::bar::baz is effectively a single unstructured string - it doesn't imply that there are hashes called foo or foo::bar. The :: is just part of the key string - it isn't syntactic sugar for a hash lookup, as is, for example, . in JavaScript.
lookup is documented at
https://puppet.com/docs/puppet/latest/hiera_automatic.html
This is now possible in puppet (v6 and later)! You use dot notation
lookup('foo::bar.key1')
See the puppet documentation here: https://puppet.com/docs/puppet/7/hiera_automatic.html#access_hash_array-elements_keysubkey_notation

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.

How get a value from a puppet resource

I have a problem with my puppet script.
I would like to get a value set in my resource file. I declare a resource like that
define checkxml(
$account = '',
$pwd = template('abc/abc.erb'),
){
if(empty($pwd)){
fail('pwd empty')
}
}
I call it via :
checkxml{"$agtaccount":
account => $agtaccount,
}
I want to get the value of $pwd. The $pwd will get is value by Template. If i try to show the value in my resource definition it's ok, I get the right value, so the Template works fine.
My problem is to get access this value after calling the ressource. I saw the getparam of stdlib but doesn't work for me.
getparam(Checkxml["$agtaccount"],"pwd")
If i try to get the account parameters instead of pwd it's ok. I think as i doesn't declare the pwd i can't get him back
How can i get him ?
Thanks for your help
Ugh, this looks dangerous. First off I'd recommend to steer clear of that function and the concept it embodies. It faces you with evaluation order dependencies, which can always lead to inconsistent manifest behavior.
As for the retrieval of the value itself - that will likely not work if the default is used. That's because on a catalog building level, there is not yet a value that is being bound to the parameter, if that makes any sense.
The resolution of final parameter values is rather involved, so there are lots of things that can go wrong with a manifest that relies on such introspective functionality.
I recommend to retrieve the desired value in a more central location (that depends on your manifest structure) and use it both when declaring the Checkxml["$agtaccount"] resource as well as its other uses (for which you are currently trying to extract it).

Resources