Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I split my hiera config by role?

Tags:

puppet

hiera

I'm using hiera to assign classes like webserver or dbserver to my nodes. The webserver class just includes apache and sets some config on it (e.g. port). Obviously I don't want to replicate this config for every node, so I put it in common.yaml. However, my common.yaml is getting big, so I want to split it up. I'd like to have one file containing the config for the webserver role, another for the dbserver role etc. I'm imagining my hiera.yaml to look something like this:

:hierarchy:
  - "fqdn/%{::fqdn}"
  - "role/%{ROLE}"
  - common

Where the role folder would contain files like webserver.yaml, appserver.yaml, dbserver.yaml. I've seen various blog posts saying that the solution is to create a custom 'role' fact, but most of them achieve this by loading that fact from a file on the agent node (e.g from /etc/role), which to me seems to defeat the point of puppet (I use puppet specifically so I don't have to log into each node and change some config every time I want it to have some new role).

To be clear, I don't want to have to edit files on the agent to get this to work, I want it all done using the config that's on the master.

I guess I could have something like the following and exhaustively list every role as an element in the hierarchy, but that doesn't seem that manageable.

:hierarchy:
  - "fqdn/%{::fqdn}"
  - "webserver"
  - "appserver"
  - "dbserver"
  - common

Is there any way to solve this?

like image 226
stripybadger Avatar asked May 15 '15 08:05

stripybadger


People also ask

How is hiera organized puppet?

Hiera looks up data by following a hierarchy — an ordered list of data sources. Hierarchies are configured in a hiera. yaml configuration file. Each level of the hierarchy tells Hiera how to access some kind of data source.

What is Eyaml?

The eyaml command is a command line interface for hiera-eyaml. It is used to create keys, encrypt and decrypt data, and act as a wrapper around a text editor.

What is hiera Yaml?

The Hiera configuration file is called hiera. yaml . It configures the hierarchy for a given layer of data. Related information. Hiera configuration layers.


2 Answers

To be able to use $Role in your hiera config, it needs to be supplied as a fact/variable, however there is a way to do this on the master instead of on the node. This is one of the things that External Node Classifiers can be used for.

Basically, you need to write a script that takes the node name and prints out yaml that includes the Role parameter's value. For example, you could have one yaml file that is just a map of node names to roles, and then the script does a lookup and prints the result (as a parameter in the linked schema). Here is an example.

There are also more robust ENC's out there, if you are interested in new tooling. For example, Foreman gives you a web interface for grouping hosts together into similar roles, setting parameters to inject into puppet runs, etc.

like image 65
Chris Pitman Avatar answered Oct 04 '22 14:10

Chris Pitman


I've come up with a solution for this. Only disadvantage is that the max number of roles is hardcoded. This will be better with hiera 3 until then try this:

/etc/puppet/hiera.yaml

 ---
:backends:
  - yaml
:yaml:
  :datadir: /etc/puppet/hieradata
:hierarchy:
  - 'nodes/%{::clientcert}'
  - 'roles/%{::role_4}'
  - 'roles/%{::role_3}'
  - 'roles/%{::role_2}'
  - 'roles/%{::role_1}'
  - common

/etc/puppet/manifests/site.pp

# Get roles
$roles = hiera_array('roles', [])

# Declare Roles in vars (not needed in puppet 4)
$role_1 = $roles[0]
$role_2 = $roles[1]
$role_3 = $roles[2]
$role_4 = $roles[3]

# Include Classes
hiera_include('classes')

/etc/puppet/hieradata/roles/webserver.yaml

---
classes:
  - nginx

# put nginx config here

/etc/puppet/hieradata/nodes/your_node_name.yaml

---
roles:
 - webserver

classes:
# put node specific stuff here
like image 36
Thomas Lohner Avatar answered Oct 04 '22 16:10

Thomas Lohner