Puppet: Node spezifische Module
Leider immer wieder nötig: Puppet Module bzw. Klassen, die explizit für eine Node benötigt werden. In der Regel wird dabei ein Modul ala „funktion_server21“ gestrikt. Dieses Modul wird dann explizit dem einen Server via Node Definition, ENC oder Hiera zugewiesen. Das bläht Hiera, den ENC oder die Node Definition unnötig auf, obwohl man sich das eigentlich auch sparen könnte.
Hier mein aktuelles Konzept zu diesem Thema, was wirklich extrem simpel ist, dennoch aber wunderbar funktioniert.
# modules/nodes/manifests/init.pp class nodes { if defined("nodes::node::${hostname}") { include "nodes::node::${hostname}" } }
Ich habe mir ein Modul „nodes“ geschrieben, das prinzipiell auf jedem Host includiert wird. Das Modul hat als einzige Funktion zu prüfen ob z.B. die Klasse node::node::server21 auf dem Puppet Master vorhanden ist. Wenn ja, wird das Modul includiert.
Wichtig an dieser Stelle ist es unbedingt defined()
statt defined(Class['nodes::node::nodename'])
zu verwenden. Das reine „define()
“ prüft ob die Klasse grundsätzlich auf dem Puppetmaster vorhanden ist, während die Erweiterte Form mit Class[]
prüft, ob die Klasse bereits im Katalog eingebunden ist. Letztes würde natürlich immer ins leere laufen, da die Klasse noch nicht includiert wurde.
Dazu beispielhaft die Klasse für den „server21“.
# modules/nodes/manifests/node/server21.pp class nodes::node::server21 { file { '/etc/apache2/conf.d/deflate.conf': ensure => absent, } }
Sollte in der Umgebung ein Overlapping bei den Hostnamen bestehen, lässt sich dieses Prinzip natürlich mit etwas mehr Logik auch mit dem Fact $::fqdn o.ä. (echo $fqdn | sed 's/\.//_//g'
) realisieren.
Damit hat man nun alle „Sonderkonstrukte“ auf einem Blick, zentral an einer Stelle in einem Modul. Diese Klasse kann man nun pauschal auf alle Nodes einbinden lassen.
node default { # Include des Moduls include 'nodes' # Oder alternativ auch via Hiera hiera_include('classes') }
Das ganze kann natürlich auch in jeder Hinsicht erweitert werden. Denkbar wäre auch nicht den Namespace nodes::node, sondern direkt nodes::$hostname zu verwenden und darunter ein komplettes Submodul zu bauen.