Hostet man die eigene Infrastruktur in der Cloud, kann der DevOps Engineer meist aus einer Vielzahl von Vorlagen an Disk Images mit den unterschiedlichsten Linux Versionen wählen (oder Windows, oder BSD,...). Dennoch müssen weitere benötigte Softwarepakete wie Datenbanken oder Webserver installiert werden. Nun kann man dazu natürlich die vom System gebotenen Werkzeuge verwenden und die Software manuell installieren. Aber nachdem wir in der Lage sind mit Terraform hunderte, tausende oder noch mehr Serversysteme zu verwalten, ginge das gänzlich an der Idee der automatisierten Cloud Provisionierung vorbei. Natürlich kann man vorhandene Tools wie Ansible, Chef, Salt oder ähnliches benutzen, um die Massen an Servern zu verwalten. Das nachträgliche Ändern von installierten Serversystemen widerspricht allerdings dem "immutable Infrastructure" Gedanken und so stellt sich die Frage nach einer alternativen Lösung. Und die gibt es. Packer.

Packer ist ein Tool zum automatisierten Erstellen von "Machine Images". Machine Images sind Snapshots oder Backups von Serversystemen. Amazon, Google oder Hetzner stellen wie oben erwähnt bereits eine große Anzahl an Machine Images zur Verfügung, aus denen man auswählen kann. Diese stellen eine minimale Installation eines Systems dar. Zum Beispiel Linux von Debian oder RedHat einer bestimmten Version. Auch unser Hoster Hetzner stellt eine Menge dieser Images zur Verfügung.

Packer nimmt nun diese Images als Grundlage für einen weiteren Installationsprozess. Dabei werden die oben erwähnten Tools wie Ansible, Chef und Co. verwendet, um einen Server mit der nötigen Software zu bespielen und die notwendige Konfiguration zu übertragen. Wie immer sagt ein Beispiel mehr als 1.000 Worte.

{
    "builders": [
        {
            "type": "hcloud",
            "image": "debian-10",
            "location": "nbg1",
            "server_type": "cx21",
            "ssh_username": "root",
            "snapshot_labels": {
                "name": "cluster"
            },
            "snapshot_name": "cluster"
        }
    ],
    "provisioners": [
        {
            "type": "ansible",
            "playbook_file": "../ansible/site.yml"
        }
    ]
}

An dieser Stelle beschreibe ich den Prozess, wie er mit unserem Provider Hetzner funktioniert. Das Konzept ist aber auf alle anderen Provider sehr leicht übertragbar.

In der Datei "cluster.json" wird im Abschnitt "builders" festgelegt welcher Maschinentyp mit welchem Machine Image als Grundlage für das neue Image dienen soll. Wir verwenden im obigen Beispiel also ein Debian 10 als Grundlage und wählen einen Servertyp bei Hetzner aus (vergleiche https://www.hetzner.com/cloud) - in unserem Beispiel den Servertyp "CX21".

Danach folgt im Abschnitt "provisioners" der Aufruf eines Ansible Scripts zur Installation der benötigten Software. Ich gehe auf diesen Ansible Teil nicht näher ein, weil ich dazu einen eigenen Blog Post schreiben werde.

Damit das ganze funktioniert, muss die Environment Variable HCLOUD_TOKEN mit dem Token aus der Hetzner Console gesetzt werden. Dieses Token regelt den Zugriff auf die Infrastruktur beim Hosting Provider. Denn startet man Packer, wird temporär ein Server erstellt und hierbei fallen bereits (überschaubare) Kosten an. Das Ansible Script auf diesem erstellten Server wird ausgeführt und - nach einem erfolgreichen Abschluss des Ansible Scripts - ein Snapshot des so konfigurierten Servers erstellt. Sowohl das Hochfahren des Servers als auch das Speichern des Snapshots führen je nach Provider zu (immer noch überschaubaren) Kosten.

Legen wir los! Mit dem folgenden Kommando wird der oben beschriebene Prozess ausgeführt.

packer build cluster.json

Loggt man sich in der Hetzner Konsole ein, so sieht man, dass nach Abschluss der Operation ein Snapshot mit dem Namen "cluster" angelegt wurde. Dieser Snapshot kann nun als Alternative zu den Machine Images des Providers als Grundlage für neue Server Instanzen verwendet werden! Alten Hasen der Systemadministration wird das Konzept als "Festplatten klonen" bekannt vorkommen.

Und nichts anderes macht Packer. Er bereitet Vorlagen auf, die danach in beliebiger Anzahl geklont werden können.

Um ein konkretes Beispiel demonstrieren zu können habe ich hier den Cloud Provider Hetzner verwendet. Das Konzept funktioniert aber bei allen Cloud Providern gleich oder zumindest sehr ähnlich. Unterstützt werden alle wichtigen und relevanten Provider wie

  • Amazon
  • Google
  • Azure
  • Digital Ocean
  • u.v.a.m.

Interessant ist, dass nicht nur Vorlagen für Cloud Provider erstellt werden können. Selbst für das eigene Rechenzentrum ist Packer geeignet, denn es unterstützt genauso VMWare, VirtualBox und das im Entwicklungsbereich sehr populäre Vagrant.

Wir sind nun also in der Lage mit Packer die Vorlagen für unsere Armada an Server Klonen vorzubereiten. Alles automatisiert und ohne manuelle Nacharbeiten! Damit kommen wir dem Konzept der Immutable Infrastructure wieder einen großen Schritt näher und ich überlege mir auch gleich, worüber ich im nächsten Teil der "Code your Infrastructure" Reihe schreiben werde.