Puppet Hiera example

puppet-hiera

Wir beschreiben hier an einem einfachen Beispiel wie puppet-hiera funktioniert.

Vagrant

Nachdem wir vagrant installiert haben legen wir uns eine Ordnerstruktur an mit welcher wir dann die Testmaschine starten bzw. provisionieren.

# mkdir -p /Users/alex/vagrant/test1
# cd /Users/alex/vagrant/test1
# vagrant init ubuntu/trusty64

Das erstellt uns im o.g. Verzeichniss eine Datei namens Vagrantfile. Jetzt könnten wir die VM direkt mittels vagrant up starten, aber wir möchten ja die VM mit puppet provisionieren und noch einige Dinge wie die IP Adresse und einen Hostnamen festelegen. nano Vagrantfile

Vagrantfile

# -*- mode: ruby -*-
# vi: set ft=ruby :

# All Vagrant configuration is done below. The "2" in Vagrant.configure
# configures the configuration version (we support older styles for
# backwards compatibility). Please don't change it unless you know what
# you're doing.
Vagrant.configure(2) do |config|

        config.vm.box = "ubuntu/trusty64"
        #config.vm.network "public_network", bridge: "your-bridge", ip: "0.0.0.0"

        config.vm.provider "virtualbox" do |vb|
                vb.memory = "2048"
        end

        config.vm.define :ntp1 do |ntp1|
                ntp1.vm.hostname = "ntp1"
        end

        config.vm.synced_folder "./puppet/", "/etc/puppet/"

        config.vm.provision :puppet, :options => ["--yamldir /etc/puppet/hiera"]  do |puppet|
                puppet.manifests_path = "puppet/manifests"
                puppet.module_path = "puppet/modules"
                puppet.manifest_file = "site.pp"
                puppet.environment = "dev"
                puppet.hiera_config_path = "puppet/hiera.yaml"
                puppet.options = "--verbose --debug"
        end
end

Puppet-Hiera

Matrix Hierarchie und Gruppen

node ssh-keys
osfamily servicenames
environment motd ssh-keys nfs
functional groups https proxy application solr database build repositories
global/ common ntp yum repositories

Oben gezeigte Matrix zeigt mögliche Gruppierungen auf wie man Puppet mit Hiera verwenden kann um seine Servertypen zu klassifizieren. Die Klassifizierung erleichter es uns später gezielt einzelne Server, Gruppen von Servern, bestimmte Umgebungen oder gar alle entsprechend einzurichten und zu definieren. Dies ist die erste Massnahme um continuous integration bzw. continuous delivery einzusetzen.

Bespiel hiera.yaml

:backends:

- yaml

:hierarchy:

- "nodes/%{::hostname}"

- "osfamily/%{::osfamily}

- "environment/%{::environment}"

- "function_groups/%{::function_groups}

- "global"

:yaml:

:datadir: "/etc/puppet/hiera"

:logger: console

1) In der o.g. hiera.yaml Datei muss für function_groups ein sogennter CUSTOM FACT gesetzt werden. httpss://docs.puppetlabs.com/facter/3.1/custom_facts.html 2) Um in der Hierarchie environment nutzen zu können muss das vorher in der Puppet.conf vorab konfiguriert werde. environment = dev Die Hierarchie wird letztendlich als Ordner im Dateisystem abgebildet. Faktisch würde Puppet sich folgendermassen durch die Ordnerstrruktur arbeiten. In diesem Bespiel verwenden wir den Nodename web1, für das Environment dev, functional_groups webserver

nodes/web1.yaml
osfamily/RedHat.yaml
environment/dev.yaml
functional_groups/webserver.yaml
global.yaml

Das heisst Puppet würde mit der weiter oben genannten yaml Datei die Werte in den darunterliegenden überschreiben wenn die Einstellungen konkurieren würden. Bsp. ich überschreibe den/die SSH Keys die für die Dev Umgebung über environment.yaml gesetzte worden sind.

Bespiel ntp

Gehen wir auf ein konkretes Beispiel ein. Nehmen wir an wir haben ein Rechenzentrum in dem die Server ein vernünftige Zeitsynchronisierung brauchen. Da es natürlich nicht jedem Server erlaubt sein soll mit einem externen ntp Server zu sprechen müssen wir uns ein Szenario bauen in dem ein ntp Master Server in der DMZ steht und mit externen ntp Servern kommunizieren darf und alle anderen dürfen lediglich mit unserem ntp Master Server sprechen. Das heisst konkret, das wir zwei yaml Datein verwenden müssen. Eine Einstellung die wir global für alle Server setzen in der global.yaml und eine für den ntp Master ntp1.yaml welche die Einstellungen aus global.yaml überschreibt.

alex@ntp1:/etc/puppet/hiera# tree
.
├── environment
│   └── dev.yaml
├── function_groups
├── global.yaml
├── nodes
│   └── ntp1.yaml
└── osfamily

nodes/ntp1.yaml

ntp::package_ensure: latest
ntp::service_enable: true
ntp::service_ensure: running
ntp::servers:
  - 0.de.pool.ntp.org iburst
  - 1.de.pool.ntp.org iburst
  - 2.de.pool.ntp.org iburst
  - 3.de.pool.ntp.org iburst
ntp::driftfile: /var/lib/ntp/drift

Der ntp Master Server darf mit den ntp Servern: 0.de.pool.ntp.org 1.de.pool.ntp.org 2.de.pool.ntp.org 3.de.pool.ntp.org komunizieren. Testen kann man das ganze wie folgt:

alex@ntp1:/etc/puppet# puppet apply --certname=ntp1 -e "notice(hiera('ntp::servers'))"
Notice: Scope(Class[main]): 0.de.pool.ntp.org iburst 1.de.pool.ntp.org iburst 2.de.pool.ntp.org iburst 3.de.pool.ntp.org iburst
Notice: Compiled catalog for ntp1 in environment dev in 0.03 seconds
Notice: Finished catalog run in 0.06 seconds

global.yaml

ntp::package_ensure: latest
ntp::service_enable: true
ntp::service_ensure: running
ntp::servers:
  - ntp1.example.com iburst
ntp::driftfile: /var/lib/ntp/drift

Alle anderen Server sind dürfen ihre Systemzeit nur mit ntp1.example.cpom abgleichen. Test:

alex@https-dev1:/etc/puppet# puppet apply --certname=https-dev1 -e "notice(hiera('ntp::servers'))"
Notice: Scope(Class[main]): ntp1.example.com iburst
Notice: Compiled catalog for https-dev1 in environment dev in 0.03 seconds
Notice: Finished catalog run in 0.06 seconds

Bespiel ssh

Im zweiten Bespiel werden wir SSH für die Entwicklungsumgebung sowie den ntp Master Server so konfigurieren, dass auf die Entwicklungsumgebung die SSH Keys und Benutzer der Entwickler, aber auf den ntp Server nur der SSH Key des zuständigen Administrators verteilt wird.

dev.yaml

ssh::keys:
  alex@Dev01.example.com:
    ensure: present
    user: alex
    type: rsa
    key: "AAAA..."  

Test:

alex@https-dev1:/etc/puppet# puppet apply --certname=https-dev1 -e "notice(hiera('ssh::keys'))"
Notice: Scope(Class[main]): {"alex@adm01.example.com"=>{"ensure"=>"present", "user"=>"alex", "type"=>"rsa", "key"=>"AAAA..."}}
Notice: Compiled catalog for https-dev1 in environment dev in 0.03 seconds
Notice: Finished catalog run in 0.06 seconds

nodes/ntp1.yaml

ssh::keys:
  admin@adm01.example.com:
    ensure: present
    user: alex
    type: rsa
    key: "AAAA..."

Test:

alex@ntp1:/etc/puppet# puppet apply --certname=ntp1 -e "notice(hiera('ssh::keys'))"
Notice: Scope(Class[main]): {"admin@adm01.example.com"=>{"ensure"=>"present", "user"=>"alex", "type"=>"rsa", "key"=>"AAAA..."}}
Notice: Compiled catalog for ntp1 in environment dev in 0.03 seconds
Notice: Finished catalog run in 0.06 seconds