Aus Linux-Magazin 04/2021

Puppet: Platzhirsch der Automatisierung

© Roman-Samborskyi / 123RF.com

Puppet schützt die Produktionsumgebung mit etablierten Abläufen. Das Urgestein des Konfigurationsmanagements ist nicht leicht zu erlernen, agiert jedoch flexibel und sicher.

Puppet ist der Methusalem unter den Lösungen für das Konfigurationsmanagement: stolze 15 Jahre gereift und aktuell in Version 7 am Start. Im Gegensatz etwa zu Ansible agiert Puppet deklarativ, beschreibt also den Zustand einer Ressource und nicht, wie man diesen erreicht.

In Listing 1 deklariert den Benutzer kermit, der existieren und der primären Gruppe muppets angehören muss. Es darf nicht gleichzeitig einen Benutzer gonzo geben. Puppet muss also in der Lage sein, den aktuellen Zustand zu ermitteln und ihn eigenständig in den deklarierten, gewünschten Zustand zu überführen.

Listing 1

Ressourcendeklaration

user { 'kermit':
 ensure => present,
 gid    => 'muppets',
}
user { 'gonzo':
 ensure => absent,
}
group { 'muppets':
 ensure => present,
}

Resource Abstraction Layer

Großen Anteil daran, wie Puppet diese Aufgabe bewältigt, hat der RAL (Resource Abstraction Layer). Dieses Herzstück von Puppet zeichnet auch für die Plattformunabhängigkeit verantwortlich. Hierzu unterscheidet RAL Typen und Provider. Ein Typ definiert die Eigenschaften einer Ressource wie »user«. Zu diesen Eigenschaften zählen Parameter wie »gid«, »home« oder »shell«. Zu jedem Typ muss es mindestens einen Provider geben, der beschreibt, wie der aktuelle Zustand ermittelt wird und wie sich der gewünschte erreichen lässt. Man bezeichnet »provider« auch als Metaparameter, da er stets bei jeder Ressource zur Verfügung steht.

Abbildung 1 enthält unter anderem den Typ »package«, der dazu dient, verschiedene Software-Pakete zu betreuen. Ist einem Typ mehr als ein Provider zugeordnet, gibt es immer einen Default-Provider. Der kann sich je nach Plattform unterscheiden. So dient auf Red-Hat-basierten Systemen der Paketmanager Yum als Default für »package«, auf Debian-Derivaten dagegen Apt. Möchte der Anwender auch GEM-Pakete verwalten, muss er den Provider explizit angeben.

Abbildung 1: Die Architektur von Puppets Resource Abstraction Layer (RAL).

Abbildung 1: Die Architektur von Puppets Resource Abstraction Layer (RAL).

Provider benutzen für ihre Arbeit immer die systemüblichen Tools. Um einen Service auf einem RHEL ab Version 7 zu verwalten, greift Puppet auf Systemctl zurück, für RPM-Pakete per Default auf Yum, bei Usern auf Useradd, Usermod und Userdel. Das Verhalten von Puppet passt sich intern immer dem zugrunde liegenden System an. Der Admin, der auf einer Ebene agiert, die davon abstrahiert, muss sich also nicht umgewöhnen. Allerdings sollte er sich schon damit beschäftigen, wie ein für ihn neues System auf die verschiedenen Anforderungen reagiert.

Entwickeln und testen

Ist der Puppet-Agent auf der Ziel-Workstation (am besten in einer virtuellen Maschine) installiert, testen Sie den Code – im Puppet-Vokabular: das Manifest – dort mit folgendem Kommando:

$ sudo puppet apply ./test.pp

Als Management-Framework für virtuelle Maschinen hat sich Vagrant [1] bewährt. Es bietet neben dem schnellen Provisionieren von Test-VMs aus der Kommandozeile heraus die unkomplizierte Möglichkeit, lokale Verzeichnisse als Dateisystem in die VM einzuhängen. So arbeiten Sie auf der eigenen Workstation mit Ihren bevorzugten Entwicklungswerkzeugen und testen das Manifest schnell mit einem »puppet apply«.

Abhängigkeiten

Im Zusammenhang mit Ressourcen kommt der Reihenfolge der Abarbeitung bei Puppet besondere Bedeutung zu. Ein zweiter Blick auf Listing 1 führt zu der Frage, warum die Gruppe muppets am Ende steht, obwohl sich die Ressourcendeklaration schon zu Beginn bei kermit auf diese Gruppe bezieht. Außerdem war eben die Rede davon, dass Puppet hier unter Linux mit Useradd arbeitet. Wer schon einmal versucht hat, beim Anlegen eines Benutzers mit Useradd mit »-g« eine auf dem System nicht existente Gruppe zu spezifizieren, kann bestätigen, dass das zu einem Fehler führt.

Puppet arbeitet die Ressourcen nicht anhand ihrer Reihenfolge im Manifest ab, sondern legt die Abfolge selbst fest. Dabei bestehen zwischen bestimmten Ressourcentypen implizite Abhängigkeiten. Im konkreten Fall bedeutet das, dass die Gruppe muppets vor dem Benutzer kermit abgearbeitet werden muss. Das setzt voraus, dass man neben dem Benutzer auch die Gruppe verwaltet. Unterlässt man das, gibt es auch bei Puppet einen Fehler. Ein weiteres Beispiel ist die Beziehung zwischen einer Datei und dem Verzeichnis, in dem sie liegt. Stehen beide im Manifest, kümmert sich Puppet immer zuerst um das Verzeichnis.

Neben den impliziten Abhängigkeiten gibt es auch solche, die Puppet nicht erkennen kann. Ein für das Unix-Umfeld typisches Beispiel bietet die Abfolge beim Einrichten eines Diensts. Erst muss man das Paket installieren, dann dessen Konfigurationsdatei anpassen und schließlich den zugehörigen Dienst starten. Erfolgt Schritt 3 vor Schritt 2, läuft der Daemon zwar, aber nicht mit der gewünschten Konfiguration. Startet man mit Schritt 3, resultiert daraus ein handfester Fehler. Beide Szenarien ließen sich mit einem zweiten Puppet-Lauf beheben, was allerdings dem Paradigma der Idempotenz widerspricht: Der Zustand nach einem Lauf hat derselbe zu sein wie nach beliebig vielen Läufen.

Puppet kennt die Metaparameter »before« und »notify«. Beide sorgen dafür, dass Puppet die eigene Ressource vor der referenzierten anwendet. Mit »notify« veranlassen Sie, wie in Listing 2 gezeigt, den Service bei Änderungen an der Konfigurationsdatei zum Neustart. Umgekehrt wirken »require« und »subscribe«. Letzteres erkennt Änderungen der referenzierten Ressource und triggert einen Neustart der eigenen.

Listing 2

Beispiel der Puppet-Klasse apache

class apache(
 String $package_name,
 Stdlib::Absolutepath $config_file,
 String $service_name,
 Stdlib::Ensure::Service $ensure = 'running',
 Boolean                 $enable = true,
) {
 package { $package_name:
 ensure => installed,
 before => File[$config_file],
 }
 file { $config_file:
 ensure => file,
 content => template('apache/httpd.conf'),
 notify  => Service[$service_name],
 }
 service { $service_name:
 ensure => $ensure,
 enable => $enable,
 }
}

Nicht jeder Ressourcentyp bietet das Feature eines Neustarts. Zu den Ressourcentypen, die das beherrschen, zählen »service« und »exec«. Über »exec« führen Sie beliebige Kommandos oder Skripte aus. Es bietet Parameter, die helfen, die Idempotenz zu wahren.

Vorlagen, Funktionen, Klassen

Zu den wichtigsten Abläufen gehört es, Konfigurationsdateien zu verwalten und zu manipulieren. Das in Ruby geschriebene Puppet greift dabei auf die Ruby-Template-Engine [2] zurück, um den Inhalt von Dateien dynamisch zusammenzubauen. Sie rufen sie aus Puppet heraus mit der Funktion »template« auf. Puppet bringt von Haus aus schon eine Vielzahl von Funktionen mit, lässt sich aber auch durch selbst geschriebene erweitern.

Listing 2 demonstriert noch ein weiteres wichtiges Konstrukt, die Klasse. Eine Puppet-Klasse fasst mehrere Ressourcen zusammen, die sie dann gemeinsam anwendet. Eine Klasse lässt sich pro System beziehungsweise Node nur einmal einsetzen. Benötigen Sie dagegen einen eigenen Ressourcentyp, der auf der Anwendung mehrerer Ressourcen basiert, schreiben Sie dazu eine Defined Resource. In beiden Fällen ist die Unterscheidung zwischen Definition und Deklaration wichtig. Listing 2 zeigt eine Klassendefinition, die allein noch nichts bewirkt. Erst eine Deklaration wie in Listing 3 führt zur Anwendung der gewünschten Aktionen.

Listing 3

Klassendeklaration

class { 'apache':
 package_name => 'httpd',
 config_file  => '/etc/httpd/httpd.conf',
 service_name => 'httpd',
}

Variablen

Sowohl Klassen als auch Defined Resources lassen sich durch Variablen parametrisieren, die immer »$« als Prefix tragen. Eine Zuweisung an eine Variable erfolgt mit dem Operator »=«. In einer Parameterliste setzt das einen Default. Werden Variablen so wie im Beispiel verwendet, tragen sie zur Plattformunabhängigkeit bei: Pfade und Namen unterscheiden sich von Distribution zu Distribution. Der Geltungsbereich einer Variablen beschränkt sich zwar auf ihre Klasse, doch gelingt bei Bedarf auch der Zugriff auf eine Variable einer anderen Klasse (Listing 4, Zeile 15).

Listing 4

Unterteilung in mehrere Klassen

./apache/manifests/init.pp
class apache(
 String $package_name,
) {
 class { 'apache::install': }
 -> class { 'apache::config': }
 ~> class { 'apache::service': }
 contain apache::install
 contain apache::config
 contain apache::service
}
./apache/manifests/install.pp
class apache::install {
 $package_name = $apache::package_name
 if $facts['osfamily'] == 'redhat' {
 package { 'mod_ssl':
 ensure => installed,
 }
 }
 package { $package_name:
 ensure => installed,
 }
}

Im Zusammenhang mit Variablen bietet auch Puppet Conditions wie If-Else und Case, um den Ablauf abhängig vom Wert einer Variablen zu steuern. So benötigt man auf einem Red-Hat-System für HTTPS beim Webserver Apache zusätzlich das RPM-Paket mod_ssl (Listing 4, Zeilen 17 bis 21), das andere Distributionen nicht erfordern.

Seit Puppet 4 können und sollten Sie Parameter typisieren: Das macht Validierungen überflüssig und standardisiert die Fehlermeldungen. Zwei der in Listing 2 für »$config_file« und »$ensure« benutzten Typen sind nicht in Puppet enthalten, sondern müssen über die Stdlib (Standard Library) als Modul zur Erweiterung des Sprachumfangs geladen werden.

Module

Neben Datentypen fassen Module auch Funktionen, Klassen, Defined Resources, Templates und noch einiges mehr zusammen. Alle müssen in bestimmten Unterverzeichnissen des Modulverzeichnisses [3] liegen, damit Puppet sie immer findet (Auto Loading).

In der Regel handelt es sich bei einem Modul um eine Zusammenfassung aller benötigten Mittel, um eine Software zu konfigurieren. Puppet Forge [4] dient als Community-Portal für Module. Hier finden sich neben vielen Modulen von Hobbyisten auch eine große Zahl professionell gepflegter Module, teils von Puppet selbst (etwa für Apache) oder vom Projekt Vox Populi [5].

Jedes Modul besitzt einen eigenen Namensraum, der stets seinem Namen entspricht. Klassen- oder Defined-Resource-Namen beginnen mit dem Modulnamen; dasselbe gilt für Datentypen (siehe Listing 2). Listing 4 zeigt den Ansatz, eine Klasse in einem Modul weiter zu unterteilen. Dazu teilen Sie die Aufgaben in Installation, Konfiguration und Service auf.

Bei den Pfeilen zwischen den Klassendeklarationen handelt es sich um eine alternative Schreibweise für das Festlegen der Reihenfolge; »->« entspricht einem »before«, »~>« einem »notify«. Damit erreicht man, dass jede Ressource der einen Klasse vor denen der anderen verarbeitet wird. Die jeweilige Umkehrung gibt es ebenfalls. Jede Ressource, die bei einer Änderung einen Service-Neustart auslösen soll, kommt in die Klasse »apache::config«, nur die den Service betreffende Ressource nach »apache::install«. Die Abhängigkeiten von Ressourcen müssen Sie nun nur noch innerhalb der jeweiligen Klasse berücksichtigen.

Mit »contain« deklarieren Sie Klassen, deren Ressourcen im Unterschied zu »include« auch der übergeordneten Klasse gehören. Nur so lässt sich eine Abhängigkeitsdefinition für zum Beispiel die Klasse »apache« sinnvoll benutzen [6]. Die Idempotenz erlaubt eine Deklaration mit »class« und danach eine erneute mit »include« oder »contain«, aber nicht umgekehrt.

Wie wir im Folgenden noch sehen, sind diese Module eine große Stärke von Puppet. Zunächst betrachten wir aber, wie Puppet überhaupt mit den zu konfigurierenden Systemen kommuniziert und entscheidet, welche Ressourcen mit welchen Parametern zu welchem Host gehören.

Der Konfigurationszyklus

Sie sollten Puppet auf jeden Fall mit einem steuernden zentralen Server betreiben, dem Puppet Master. Auf jedem der zu konfigurierenden Server (den Nodes) installieren Sie einen Puppet-Agenten. Er läuft dort als Daemon und nimmt alle 30 Minuten (konfigurierbar) Verbindung mit dem Master auf. Diese per TLS verschlüsselte Verbindung wird beidseitig durch ein Zertifikat authentisiert. Dabei übernimmt der Master zumeist auch die Aufgabe einer CA für die Zertifikatsverwaltung.

Nach dem Herstellen der Verbindung übermittelt der Agent die von ihm ermittelten Facts an den Server (Abbildung 2). Sie stehen dann dort als Variablen in einem den Klassen übergeordneten Geltungsbereich zur Verfügung, dem Top-Scope. Facts enthalten wichtige Informationen über Art und Version des Betriebssystems, die Hardware, eingehängte Dateisysteme oder die Inhalte von selbst geschriebenen Facts (Custom Facts).

Abbildung 2: Der Datenfluss während der Abarbeitung eines Puppet-Laufs.

Abbildung 2: Der Datenfluss während der Abarbeitung eines Puppet-Laufs.

Anhand der Facts ermittelt der Server das Manifest für den abfragenden Knoten. Diese Informationen können wie in Listing 5 auf dem Server liegen, werden aber in den meisten Fällen über eine Schnittstelle von einem ENC (External Node Classifier) wie Foreman oder einer CMDB erfragt. Das so bestimmte Manifest aus Klassen, Variablen, Templates und Ressourcen kompiliert Puppet auf dem Server zum Catalog. Er enthält keine Klassen, Templates oder Variablen mehr und wird so zurück an den Agenten übermittelt.

Listing 5

Node-Deklaration

node "certname.node.one" {
 include role::cms
}
node "certname.node.two" {
 include role::webserver
}

Der Agent empfängt mit dem Catalog den gewünschten Zustand für seinen Knoten. Er prüft nun mithilfe des RAL den aktuellen Zustand der im Catalog enthalten Ressourcen und überführt diese gegebenenfalls in den gewünschten Zustand. Das Protokoll über diesen Puppet-Lauf sendet der Agent abschließend als Report an den Master, der ihn über einen entsprechenden Handler weiterreicht. Als Ziel eines Reports kommen unter anderem Log-Dateien, die PuppetDB oder Foreman infrage.

Pflege des eigenen Codes

Ihren Code, der in der Regel aus einer Mischung eigener und vieler Upstream-Module aus der Puppet Forge besteht, pflegen Sie am besten in einem Git-Repository. Als Standard gilt es, ein Control-Repo zu betreiben, in dem eine Liste von Modulen (in der Datei »Puppetfile«) samt der zu verwendenden Modulversionen liegt. Diese Module können aus der Forge stammen oder aus anderen Git-Repos. Selbstgeschriebene oder gepatchte Upstream-Module pflegt man in der Regel im selben Git als jeweils eigenes Repository mit eigenen Versionen. Sofern man keinen ENC verwendet, befindet sich im Control-Repo unter »manifests/site.pp« die in Listing 5 gezeigte Deklaration der einzelnen Knoten.

In einem Branch des Control-Repositorys können Sie andere Modulversionen hinterlegen, etwa neuere, ungetestete. Beim Push in einen der Branches baut die Software R10k [7] (im Paket puppet-bolt) aus jedem Branch und den dortigen Informationen über Module jeweils ein eigenes Puppet-Environment auf dem Server zusammen. Der ENC steuert, welches Environment der Agent anfragt. So lassen sich beliebig viele unterschiedliche Testszenarien aufbauen und vor dem Überführen in die Produktion ausgiebig testen. Ein Push in ein zum Modul gehöriges Git-Repo triggert ebenfalls einen R10k-Aufruf, der dann jedoch lediglich das Modul in der Version aktualisiert – das aber in allen Environments. Hierbei kann man sich nicht nur auf getaggte Versionen beziehen, sondern auch auf Branches oder Commits.

Die Integration von R10k mit einem Git und die nötigen Hooks bilden keinen Bestandteil der OSS-Variante von Puppet, lassen sich aber von erfahrenen Admins leicht nachbauen.

Hiera: Code und Daten trennen

Eine weitere wichtige Sache, die man in der Regel direkt im Control-Repo pflegt, ist Hiera. Dabei handelt es sich um einen hierarchischen Key-Value-Store, der anhand von Suchparametern seinen Datenbestand abfragt. Dahinter steht der Gedanke, zum Beispiel für den Code in Listing 2 auf verschiedenen Plattformen unterschiedliche Werte für »$package_name«, »$config_file« und »$service_name« zu ermitteln, abhängig davon, was der Agent mittels Fact als Betriebssystem übermittelt hat.

Dazu hinterlegen Sie zunächst eine Hierarchie in der Datei »hiera.yaml« im Control-Repo (Listing 6). Die Daten liegen im einfachsten Fall im YAML-Format ebenfalls im Control-Repos, dort unterhalb von »./data/«. Das Feature Automatic Parameter Lookup von Puppet nimmt bei jeder Deklaration einer Klasse automatisch einen Hiera-Lookup nach Werten für seine Parameter vor. Die Namen der Keys in Hiera müssen dem Namensraum der jeweiligen Klasse entsprechen (Listing 7).

Listing 6

Hiera-Hierarchie festlegen

version: 5
defaults:
 datadir: data
 data_hash: yaml_data
hierarchy:
 - name: 'Node specific'
 path: 'nodes/%{trusted.certname}.yaml'
 - name: 'Operating System Family'
 path: '%{facts.os.family}.yaml'
 - name: 'common'
 path: 'common.yaml'

Listing 7

Hiera-Dateien für Red Hat und Debian

$ cat ./data/RedHat.yaml
apache::package_name: httpd
apache::config_file: /etc/httpd/httpd.conf
apache::service_name: httpd
$ ./data/Debian.yaml
apache::package_name: apache2
apache::config_file: /etc/apache2/apache2.conf
apache::service_name: apache2

Da eine Wertzuweisung auch bei einer Deklaration oder durch einen gesetzten Default erfolgen kann, stellt sich die Frage nach der Reihenfolge der Auswertung. Der Default gilt als schwächstes Glied der Kette nur, wenn es weder eine explizite Deklaration gab noch ein Hiera-Lookup einen Wert liefert. Die Zuweisung in einer Deklaration mittels »class« ist am stärksten, damit verbleibt für das Automatic Parameter Lookup der Platz in der Mitte.

Das Parameter Lookup erlaubt es, eine Klasse immer mit »include« oder »contain« zu deklarieren, sofern der Lookup einen Wert für die Parameter liefert (zum Beispiel mit »include apache«). Das kann Defaults überschreiben, muss es aber nicht zwangsläufig. Auch innerhalb eines Moduls lässt sich ein Hiera betreiben, das allerdings nur Key-Values für den Namensraum des Moduls selbst speichert. Alle dortigen Werte lassen sich bei Bedarf im Environment-Hiera des Control-Repos nochmals überschreiben.

Mehr Abhängigkeiten

Es gibt Abhängigkeiten zwischen Ressourcen, die sich nicht nur auf einen Host beschränken. Ein Webcluster mit vorgeschaltetem Load Balancer kann erst dann einen neuen Cluster-Knoten aufnehmen, wenn der fertig konfiguriert ist. Puppet kennt für so einen Fall Exported Resources. Die Mitgliedschaft im Cluster deklariert man als solche Exported Resource auf dem neuen Cluster-Knoten. Statt sie aber dort anzuwenden, speichert der Master sie in der PuppetDB.

Beim nächsten Puppet-Lauf auf dem Load Balancer werden alle Cluster-Mitglieder inklusive des neuen in die dortige Konfiguration eingetragen; der Cluster hat damit ein neues, funktionsfähiges Mitglied. Im Manifest zum Load Balancer erledigt das ein Collector, der auf dem Server die PuppetDB nach entsprechenden Ressourcen befragt und sie im Catalog an den Agenten übermittelt. Die sonst optionale PuppetDB ist für Exported Resources also eine zwingende Voraussetzung.

Rollen und Profile

Abhängigkeiten, insbesondere solche, die sich auf einen Host beschränken führten in den Anfangstagen von Puppet schnell zu Problemen. Das Bestreben, die Übersicht zu behalten und sich nicht in den Abhängigkeiten zu verheddern, führte zum Konzept von Rollen und Profilen.

Dabei gliedern sich die Module in drei Ebenen. Die unterste bilden die Component Modules, die sich generisch um die Konfiguration von Software kümmern. Sie lassen sich zu großen Teilen aus der Puppet Forge beziehen. Component Modules sollten sich jeweils nur um die Belange der spezifischen Software kümmern, das Apache-Modul also nur um den Webserver, nicht um Log-Rotation oder Firewall-Konfiguration – das erledigen eigene Component Modules.

Auf der zweiten Ebene, der Implementationschicht, führen einzelne Klassen eines Moduls die benötigten Component Modules zusammen. Das entsprechende Modul namens »profile« müssen Sie selbst erstellen. Darin führen Sie etwa für den eigenen Webserver die Konfiguration von Log-Rotation und Firewall-Konfiguration zusammen.

Klassen auf beiden Ebenen dürfen Parameter verwenden und lassen sich mittels Hiera konfigurieren. In der Rolle, der obersten Schicht, dürfen Sie hingegen laut Konzept nur Profilklassen deklarieren. So fasst beispielsweise das CMS als Rolle die Profile für Webserver, Applikation und Datenbank zusammen. Eine solche Klasse des Moduls »role« bezeichnet man auch als Business-Klasse oder -Rolle.

Durch diese Abstraktion reduzieren sich zu definierende Abhängigkeiten zwischen Ressourcen drastisch, und gemeldete Dependency Cycles treten deutlich seltener auf.

Was Puppet nicht kann

Puppet ist für das Konfigurationsmanagement konzipiert, also nicht für das Verwalten oder Aktualisieren von Software. Ressourcen vom Typ »package« lassen sich zwar auf eine Version des Pakets festlegen, und die könnte sich im Lauf der Zeit auch ändern, das sollte aber tunlichst unterbleiben. Neben den unvermeidlichen Problemen mit Paketmanagern bei Versionssprüngen gäbe es dann auch Schwierigkeiten bei Downgrades.

Ließe man so etwas zu, könnte es passieren, dass beim nächsten generellen System-Update der Puppet-Lauf ein Downgrade versucht. Die klare Empfehlung lautet, ein Software-Management wie Spacewalk oder Satellite beziehungsweise Foreman/Katello zu etablieren, um unterschiedliche Software-Stände in unterschiedlichen Versionen der Software-Repositories anzubieten.

Da Puppet asynchron arbeitet, taugt es auch nicht als Orchestrierungswerkzeug wie etwa Ansible, um gewisse Arbeiten gleichzeitig auszuführen. Ein typisches Beispiel sind Updates oder Rekonfigurationen an Cluster-Knoten; dafür eignet sich Ansible besser. Setzen Sie allerdings schon Puppet ein, dann lohnt sich ein Blick auf Puppet Bolt [8], das Orchestrierungswerkzeug von Puppet. Bolt arbeitet mit Tasks, die man in jeder beliebigen Sprache schreiben kann. Das schließt auch Puppet mit ein, und man profitiert dann vom RAL. Auf diese Weise lässt sich ein und derselbe Code plattformübergreifend verwenden.

Infrastruktur und Skalierung

Puppet setzt für den professionellen Einsatz eine nicht unerhebliche Infrastruktur voraus. Sie benötigen den Puppet-Server inklusive CA, ein steuerndes Git mit R10k, optional ein Software-Management und eine GUI fürs Reporting. Hinzu kommt die PuppetDB, die Sie als Anwendung mit einer PostgreSQL-Datenbank realisieren, wenn Sie Exported Resources benötigen.

Der Autor setzt zumeist auf Foreman fürs Reporting und ENC, erweitert um das Plugin Katello zum Software-Management, was ebenfalls ein PostgreSQL voraussetzt. Eine PuppetDB bietet sich somit an und verursacht keinen großen Mehraufwand. Dazu kommt die GitLab Community Edition als Git, um eine GUI mit integriertem Issue Management zu bekommen.

Ein Puppet-Server kann rund 500 zu konfigurierende Hosts bedienen. Werden es mehr, skaliert Puppet horizontal sehr gut: Weitere Puppet-Server, die ebenfalls Catalogs kompilieren, lassen sich einfach integrieren.

Fazit

Puppet ist komplex, schwergewichtig und nicht ganz leicht zu erlernen. Beherrscht man es jedoch erst einmal, erweist es sich als flexibel und sicher. Einen großen Vorteil stellen die vielen gepflegten Module in der Puppet Forge dar. Sie erfordern in der Regel ebenfalls eine Einarbeitungszeit, lassen dann aber zumeist kaum Wünsche offen.

Puppet schützt die eigene Produktionsumgebung mit etablierten Abläufen. Das bedeutet aber auch, sich von von dem Gedanken zu verabschieden, man könne mal eben schnell Code dafür schreiben: Den gilt es gewissenhaft zu testen und über ein Staging in die Produktion zu überführen. Lediglich Konfigurationsparameter bei verwalteten Applikationen erfordern keine solchen Tests und lassen sich in Hiera leicht anpassen. (jcb/jlu)

Infos

  1. HashiCorp Vagrant: https://www.vagrantup.com
  2. Ruby Template Language: https://puppet.com/docs/puppet/5.5/lang_template_erb.html
  3. Verzeichnisstruktur: https://puppet.com/blog/magic-directories-guide-to-puppet-directory-structure
  4. Community-Portal für Module: https://forge.puppet.com
  5. Community-Projekt zur Pflege von Modulen: https://voxpupuli.org
  6. Class Containment: https://puppet.com/blog/class-containment-puppet
  7. Puppet-Environments automatisch erzeugen: https://github.com/puppetlabs/r10k
  8. Orchestrieren mit Puppet Bolt: https://puppet.com/docs/bolt/latest/bolt.html
DIESEN ARTIKEL ALS PDF KAUFEN
EXPRESS-KAUF ALS PDFUmfang: 6 HeftseitenPreis €0,99
(inkl. 19% MwSt.)
LINUX-MAGAZIN KAUFEN
EINZELNE AUSGABE Print-Ausgaben Digitale Ausgaben
ABONNEMENTS Print-Abos Digitales Abo
TABLET & SMARTPHONE APPS Readly Logo
E-Mail Benachrichtigung
Benachrichtige mich zu:
0 Kommentare
Älteste
Neuste Beste Bewertung
Nach oben