Puppet / Teil 2 – Inventarisierung und erstes Manifest

Im letzten Beitrag haben wir den Boden für unsere Puppet-Infrastruktur mit Server-/ und Client -Installation bereitet. Nun soll der zweite Teil des Artikels eine erste Funktionsanweisung (das sogenannte “Manifest”) samt Inventarisierung der Puppet-Clients behandeln.
Um den Umfang nicht allzu sehr ausufern zu lassen, werde ich auf Mechaniken wie die “environments” oder die Installation und Bedienung einer grafischen Oberfläche verzichten. Außerdem wird das vorgestellte Manifest lediglich mit einer APT basierten Distribution kompatibel sein. Die grundlegende Erstellung und Syntax unterscheidet sich jedoch nicht von z.B. einer YUM basierten Distribution sodass der Inhalt relativ problemlos angepasst werden kann.

Beginnen wir mit dem Durchwühlen von einem der (meiner Meinung nach) unübersichtlichsten Ordnerstrukturen, welche jemals einen ext4-Dateisystem Boden betreten hat. unter /etc/puppetlabs/code/environments/production/ findet ihr zwei Unterordner:
“manifests” und “modules”. Beide sind von existenzieller Wichtigkeit, da in ihnen Inventar der Puppet-Clients und die Manifeste mit ihren Regelsätzen abgelegt werden.

Ein neues Manifest erstellen wir, indem wir zunächst die Ordnerstruktur dafür erzeugen:

sudo mkdir -p /etc/puppetlabs/code/environments/production/modules/update_packages/manifests/

Mit diesem Befehl wird neben dem Ordner “update_packages” auch gleichzeitig der Unterordner “manifests” erstellt. “update_packages” ist der Name des Manifests. Er könnte aber ebenso gut auch KlausDieter heißen, wäre hinterher beim zuordnen allerdings von entscheidendem Nachteil. Dass der Unterordner manifests vorhanden sein muss, ist eine Eigenheit von Puppet. Man muss es einfach so hinnehmen.
Innerhalb der letzten Ordnerebene wird nun die Datei “init.pp” erzeugt:

sudo nano /etc/puppetlabs/code/environments/production/modules/update_packages/manifests/init.pp

In dieser können wir uns nun im Rahmen der YAML-Puppet-Syntax austoben.
Folgenden Inhalt schmeiße ich mal ungefragt in den Raum und gebe hinterher eine Erklärung dazu ab:

class update_packages {

### Refresh software repository
exec { "apt-update":
 command => "/usr/bin/apt-get update"
}

### Update software packages
exec { "apt-upgrade":
 command => "/usr/bin/apt-get --quiet --yes --fix-broken upgrade",
 path => "/usr/bin:/usr/sbin:/bin:/usr/local/bin:/usr/local/sbin:/sbin",
 require => Exec["apt-update"],
 timeout => 1800,
}

}

Sakrileg! “Er erzeugt mit Puppet ein Manifest, welches über eine Kommandoausführung die Clients dazu auffordert, Updates einzuspielen!” höre ich die Puppet-Affinen raunen.
Und ja, ich weiß, dass dies nicht die smarteste Möglichkeit ist, Puppet zu benutzen. Puppet ist in erster Linie ein Tool, welches Systemzustände setzt und nicht irgendwelche Kommandos Remote ausführt, dessen bin ich mir voll bewusst.
Aber hey, es funktioniert trotzdem.

So, und nun gehe ich mal auf den Inhalt ein. In der ersten Zeile wird eine Klasse erzeugt. Puppet arbeitet innerhalb der Manifeste mit Klassen, quasi als Unterkategorisierung. Es lassen sich auch mehrere Klassen in einem Manifest bündeln. Der Einfachheit halber erzeugen wir uns aber nur eine einzige mit dem Namen “update_package”. Es ist fundamental wichtig, dass diese Oberklasse denselben Namen trägt, wie der zuvor erzeugte Ordner (wir erinnern uns an das Beispiel “KlausDieter”), da wir sonst später in einen Syntax Error hineinrennen.
In dieser Klasse legen wir uns sogenannte Ressourcen-Typen an. Anweisungen werden in keiner bestimmten Reihenfolge abgearbeitet, dies können wir allerdings mit einem Parameter steuern (Erklärung folgt weiter unten). Eingeläutet wird der Ressourcen-Typ in unserem Fall mit dem Stichwort “exec”, dem wiederrum einige weitere Kommandos zur Auswahl stehen. Mit “command” haben wir die Möglichkeit, das Kommando anzugeben, welches Remote ausgeführt werden soll. Wichtig ist es, jeden Ressourcen-Typ mit geschweiften Klammern korrekt zu markieren, ansonsten gibt es Syntax-Fehler und da ist Puppet richtig pingelig!
Der nächste Block ist ähnlich aufgebaut wie der vorherige, nur etwas umfangreicher. Ich gehe kurz auf die einzelnen Funktionsanweisungen ein:

command = Gibt an, welches Kommando ausgeführt werden soll
path = Erweitert die PATH-Variable um die angegebenen Orte. In unserem Fall recht sinnfrei, da wir mit dem Kommando in “command” ohnehin den vollständigen Pfad angegeben haben
require = Erst nachdem der Ressourcen-Typ “apt-update” durchgelaufen ist, wird dieser Block ausgeführt
timeout = Zeit in Sekunden, die der Programmaufruf Zeit hat um in einen Timeout zu laufen

Somit wäre bereits das erste selfmade Puppet-Manifest erstellt. Nun muss unserem Server nur noch bekannt gemacht werden, wem die Ehre gebührt dieses Manifest ausführen zu dürfen.

Legen wir also eine weitere Datei an:

nano /etc/puppetlabs/code/environments/production/manifests/site.pp

Hier sind wir abermals in der Pflicht, dem Puppetserver eine brauchbare Syntax im Yaml-Format zu liefern. Es folgt wieder der Inhalt der Datei und anschließend die dazugehörige Erklärung:

node 'xubuntu-vm.fritz.box' {
  include update_packages
}

node default {
  notify { 'Dieser Client ist keinem Manifest zugewiesen': }
}

Neue Clients (wie auch die “xubuntu-vm”) werden mit dem vorangestellten Schlagwort “node” als Client gekennzeichnet. Es folgt eine geschweifte Klammer und das Manifest oder die Manifeste, die wir diesem Client oder den Clients (mehrfachauswahl möglich) zuweisen. Es ist außerdem möglich, mehrere Nodes (z.B. jene mit einer aufsteigenden Nummer) mit einer regex Syntax zusammenzufassen.
Außerdem haben wir eine zweite Node-Definition für “default” erstellt. default ist ein Zauberwort im Puppet-Jargon und umfasst sämtliche Clients, die nicht Teil irgendeiner node-Definition sind. Lassen diese den Puppet-Agent nämlich durchlaufen, werden sie lediglich mit der vorgefertigten Meldung “Dieser Client ist keinem Manifest zugewiesen” abgewiesen.

Alles erledigt? Dann wird sich unser Client bei der nächsten Ausführung des Agenten die Anweisung holen, die wir im Manifest hinterlegt haben. Um diesen Vorgang zu beschleunigen und die Ausgabe im Terminal sichtbar zu machen, können wir ein wenig nachhelfen und führen, wie im ersten Teil des Artikels erwähnt, den Puppet Agent auf dem Client aus.

sudo puppet agent -t

Der Durchlauf könnte, je nach Update Stand der Maschine, ein wenig Zeit in Anspruch nehmen. Das Ergebnis sollte wie folgt aussehen.

Spaßeshalber können wir nun noch den Puppet Agenten auf dem Server selbst ausführen und schauen, ob uns unsere Dummy-Nachricht angezeigt wird, die in etwa folgendermaßen aussehen sollte.

Glückwunsch. Neben der groben Puppet-Infrastruktur, ist nun auch das erste Manifest und ein kleines Mini-Inventar vorhanden, auf dem weiter aufgebaut werden kann.

Kommentar verfassen

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

Scroll to Top