Using hiera_hash for augeas changes in hiera puppet

434 views Asked by At

I've created yaml files for each environment type dev, qa, integration. However there are multiple dev environments and i want to override some changes via host specific yaml files.

Hiera
|--host
|  |-dev1.internet.com
|  |-dev2.intranet.com
|--servertype
|  |-dev
|  |-qa

dev.yaml
augeas_xml:
  - 'set /root/node/servername/#text 'dev'
  - 'set /root/node/serverlocation/#text 'London'
  - 'set /root/node/ntp/#text '123.123.123.123'

dev1.internet.com.yaml
augeas_xml:
  - 'set /root/node/serverlocation/#text 'New York'
  - 'set /root/node/ntp/#text '123.123.123.125'

dev2.intranet.com.yaml
augeas_xml:
  - 'set /root/node/serverlocation/#text 'Accrington'

I need a way to get the config of dev1.internet.com.yaml to have the following

augeas_xml:
  - 'set /root/node/servername/#text 'dev'
  - 'set /root/node/serverlocation/#text 'New York'
  - 'set /root/node/ntp/#text '123.123.123.125'

hiera_array is not giving me the desired result and hiera_hash is giving me the following error: Hiera type mismatch for key 'augeas_xml': expected Hash and got Array

The host specific settings are not taking priority over the environment specific settings. The example i gave is for a small set of servers. I'm using puppet to manage hundreds of servers. I could use hiera and create a yaml file for every single host. However, I want to have a default.yaml and be able to override the changes in the host.yaml

---
:hierarchy:
  - "host/%{::fqdn}"
  - "server_type/%{server_type}"
  - default
:backends:
  - yaml
:yaml:
  :datadir: "/puppet/hieradata/%{::environment}"
:merge_behavior: deeper

The latter is producing

    dev1.internet.com.yaml
    augeas_xml:
      - 'set /root/node/serverlocation/#text 'New York'
      - 'set /root/node/ntp/#text '123.123.123.125'
      - 'set /root/node/servername/#text 'dev'
      - 'set /root/node/serverlocation/#text 'London'
      - 'set /root/node/ntp/#text '123.123.123.123'

but I want it to do

    dev1.internet.com.yaml
    augeas_xml:
      - 'set /root/node/servername/#text 'dev'
      - 'set /root/node/serverlocation/#text 'London'
      - 'set /root/node/ntp/#text '123.123.123.123'
      - 'set /root/node/serverlocation/#text 'New York'
      - 'set /root/node/ntp/#text '123.123.123.125'
1

There are 1 answers

0
Dominic Cleal On BEST ANSWER

It'd be much simpler to keep the Augeas commands and paths out of your data files and only put the important bits of data - the name, location, and server address - in the data files. The Augeas commands are most definitely implementation-specific, not data.

For example:

dev.yaml

servername: 'dev'
serverlocation: 'London'
ntp: '123.123.123.123'

dev1.internet.com.yaml

serverlocation: 'New York'
ntp: '123.123.123.125'

dev2.intranet.com.yaml

serverlocation: 'Accrington'

Then in your manifest, you have something like this:

$servername = hiera('servername')
$serverlocation = hiera('serverlocation')
$ntp = hiera('ntp')

augeas { 'node':
  context => '/files/root/node',
  changes => [
    "set servername/#text '$servername'",
    "set serverlocation/#text '$serverlocation'",
    "set ntp/#text '$ntp'",
  ],
}

(note the other Augeas resource properties are missing and should be replaced by your own)