One typical example is IP address and NTP/DNS servers, the IP address is unique for each server and NTP/DNS is global. I built a linux-network test module to demonstrate the usage of Hiera
Hiera supports yaml and Json as backend by default, however you can write your custom backend using Hiera API.
Define datadir in hiera.yaml
[root@server1 modules]# cat /etc/puppetlabs/puppet/hiera.yaml --- :backends: - yaml :hierarchy: - defaults - "%{clientcert}" - "%{environment}" - global :yaml: # datadir is empty here, so hiera uses its defaults: # - /var/lib/hiera on *nix # - %CommonAppData%\PuppetLabs\hiera\var on Windows # When specifying a datadir, make sure the directory exists. :datadir: /etc/puppetlabs/puppet/hieradata
Set all values in YAML file instead of manifest file
You can also add class name in YAML file, then assign class to node with hiera_include
[root@server1 modules]# cat /etc/puppetlabs/puppet/hieradata/global.yaml --- # # ntp.conf ntpservers: [10.1.1.11, 10.1.1.12] #resolv.conf domainname: example.com searchdomain: [example1.com, example2.com] nameservers: [10.1.1.13, 10.1.1.14] [root@server1 modules]# cat /etc/puppetlabs/puppet/hieradata/server1.example.com.yaml eth1: device: eth1 ipaddr: 172.16.1.2 netmask: 255.255.255.0 routes: ['192.168.1.0/24 via 172.16.1.254', '192.168.2.0/24 via 172.16.1.254'] gateway: 172.16.1.254 eth3: device: eth3 ipaddr: 172.16.1.3 netmask: 255.255.255.0 #routes: ['192.168.1.0/24 via 172.16.1.254', '192.168.2.0/24 via 172.16.1.254']Execute the whole class or a function of the class in site.pp, the codes in site.pp become universal.
The site.pp manifest file is just generic code
[root@server1 modules]# cat /etc/puppetlabs/puppet/manifests/site.pp node "server1" { include "linux-network" } node "server2" { linux-network::setinterface { 'eth1': } }linux-network module manifest files
[root@server1 modules]# cat ./linux-network/manifests/init.pp class linux-network { linux-network::setinterface { 'eth1': ; 'eth3': } linux-network::setroute { 'eth1': ; 'eth3':} linux-network::setconf_ntp {'ntp.conf':} linux-network::setconf_resolv {'resolv.conf':} } [root@server1 modules]# cat ./linux-network/manifests/setconf_ntp.pp define linux-network::setconf_ntp ( ) { $ntpservers=hiera_array('ntpservers') file {"/etc/ntp.conf": ensure => present, owner => root, mode => 644, content => template("${module_name}/ntp.conf.erb") } } [root@server1 modules]# cat ./linux-network/manifests/setconf_resolv.pp define linux-network::setconf_resolv ( ) { $domainname=hiera('domainname') $searchdomain=hiera_array('searchdomain') $nameservers=hiera_array('nameservers') file {"/etc/resolv.conf": ensure => present, owner => root, mode => 644, content => template("${module_name}/resolv.conf.erb") } } [root@server1 modules]# cat ./linux-network/manifests/setinterface.pp define linux-network::setinterface ( ) { $device=$title $eth=hiera($device) $ipaddr=$eth['ipaddr'] $netmask=$eth['netmask'] $gateway=$eth['gateway'] file {"/etc/sysconfig/network-scripts/ifcfg-$device": ensure => present, owner => root, mode => 644, content => template("${module_name}/ifcfg.erb") } } [root@server1 modules]# cat ./linux-network/manifests/setroute.pp define linux-network::setroute ( ) { $device=$title $eth=hiera($device) $routes=$eth['routes'] file {"/etc/sysconfig/network-scripts/route-$device": ensure => present, owner => root, mode => 644, content => template("${module_name}/route.erb") } }linux-network module template files
[root@server1 modules]# cat ./linux-network/templates/ifcfg.erb DEVICE=<%=@device %> BOOTPROTO=static ONBOOT=yes USERCTL=no IPADDR=<%=@ipaddr%> NETMASK=<%=@netmask%> <%- if @gateway =~ /(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})/ -%> GATEWAY=<%=@gateway %> <%- end -%> [root@server1 modules]# cat ./linux-network/templates/ntp.conf.erb tinker panic 0 restrict default kod nomodify notrap nopeer noquery restrict -6 default kod nomodify notrap nopeer noquery restrict 127.0.0.1 restrict -6 ::1 # <%- @ntpservers.each do |x| -%> server <%= x %> <%- end -%> driftfile /var/lib/ntp/drift [root@server1 modules]# cat ./linux-network/templates/resolv.conf.erb # # resolver configuration file... # options timeout:1 attempts:8 rotate domain <%=@domainname %> <%- if !@searchdomain.empty? -%> search <%=@domainname -%> <%= @searchdomain.join(' ') %> <%- end -%> <%- @nameservers.each do | x | -%> nameserver <%= x %> <%- end -%> [root@server1 modules]# cat ./linux-network/templates/route.erb <%- if defined?(@routes) -%> <%- @routes.each do | x | -%> <%=x %> <%- end -%> <%- end -%>