Kolumne: Quality Time

Ansible als Alternative zu Puppet oder Chef
Kommentare

Spätestens seit dem Siegeszug von DevOps gehört es zum guten Ton eines Entwicklungsteams: Die benötigte Serverkonfiguration wird direkt im Projekt gehalten, das Einrichten und Aktualisieren aller Systeme wird auf Knopfdruck automatisiert, was Zeit, Nerven und letztendlich auch Geld spart. Die Konfigurationsdateien für Orchestrierungswerkzeuge wie Puppet und Chef, die ganze Serverfarmen, aber auch einzelne virtuelle Maschinen betreuen können, werden gemeinsam mit dem Quellcode des Projekts versioniert.

Gegen diese beiden Platzhirsche der Szene tritt Ansible seit seiner Geburt vor zwei Jahren als pragmatische Open-Source-Lösung für Konfigurationsmanagement und Administration an. Dabei legt das Tool Wert auf Einfachheit und Lesbarkeit der Konfiguration – Eigenschaften, die den etablierten Lösungen oft fehlen. Als kleines Beispielszenario soll hier mit Ansible der Apache-Webserver auf einem Ubuntu-System installiert und eine Vhost-Konfiguration erstellt werden. Aus Platzgründen werden hier einige Details nicht dargestellt, Sie können den gesamten Quellcode aber auf GitHub einsehen und ausprobieren.

Ansible benötigt mindestens zwei Konfigurationsdateien: ein so genanntes Playbook, das die Regieanweisungen – also die auszuführenden Befehle – enthält, und eine Inventory-Datei, die beschreibt, welche Computer administriert werden sollen und in welche Gruppen diese aufgeteilt sind. Wir schauen uns zuerst das Playbook an, das hier provision.yml heißt:

---
 
- hosts: backend 
   sudo: yes 
   roles: 
     - role: webserver 
       vhosts: 
         - { hostname: 'ansible.local', dir: '/home/vagrant/ansible/htdocs' }

Diese YAML-Datei beschreibt eine Hostgruppe namens backend, beliebige weitere Hostdefinitionen können mit Spiegelstrichen hinzugefügt werden. Für die Hosts in der backend-Gruppe sollen die anstehenden Befehle mit sudo, also als Root-Benutzer, ausgeführt werden. Anstatt diese Befehle jedoch direkt im Playbook aufzulisten, was durchaus möglich wäre, wird als Best Practice die Modularisierung mit Rollen genutzt. Im konkreten Fall wird der Hostgruppe die Rolle webserver zugewiesen.

Hosts dieser Gruppe spielen also die Rolle webserver und sollen entsprechend ausgestattet werden. Jede Hostgruppe kann beliebig viele Rollen spielen, die als Gesamtergebnis alle auszuführenden Tasks definieren. Andere denkbare Rollen wären z. B. database für die Installation von MySQL oder javascript für Node.js und weitere Tools. Im gezeigten Fall erhält die Rolle webserver beim Aufruf den Parameter vhosts, der eine Liste von weiteren Konfigurationseinheiten enthält. Deren Format ist frei wählbar und wird später in einem Template zum Ausfüllen von Config-Files verwendet.

Per Konvention liegen die Dateien zu allen Rollen im Unterverzeichnis roles/ und jede Rolle wird dort durch ihren Ordnernamen identifiziert. Das folgende Listing zeigt die Befehle der Beispielrolle, die in der Datei roles/webserver/tasks/main.yml zu finden sind.

--- 
- name: Install Apache 
  apt: pkg=apache2-mpm-prefork state=present

- name: Delete default Apache vhost 
  file: path=/etc/apache2/sites-enabled/000-default state=absent 
  notify: Restart Apache 

- name: Generate Vhosts 
  template: 
    src=vhost.conf 
    dest=/etc/apache2/sites-enabled/{{ item.hostname }}.conf 
  with_items: vhosts 
  notify: Restart Apache 

Diese Liste von Anweisungen wird von Ansible der Reihenfolge nach ausgeführt, was einen gravierenden Unterschied zu beispielsweise Puppet darstellt. Der erste Befehl wird als Install Apache dokumentiert und tut auch genau dies: Über das Ansible-Modul apt wird Ansbible instruiert, dafür zu sorgen, dass das Debian-Paket apache2-mpm-prefork installiert, also present ist. Praktisch: Ist das bereits der Fall, z. B. durch einen früheren Lauf von Ansible, wird keine weitere Installation ausgeführt.

Als zweite Task soll Ansible sicherstellen, dass die Default-Vhost-Konfiguration des Apachen nicht vorhanden ist (state=absent). Auch hier gilt, dass Ansible den Befehl nicht ausführt, falls die Datei nicht existiert. Mithilfe der Option notify wird Ansible instruiert, den Webserverprozess neu zu starten, wenn die Änderung durchgeführt wurde.

template nimmt als letzten Befehl der Rolle eine Vorlagendatei (src), füllt diese aus und legt sie unter einem entsprechenden Namen (dest) ab. Die Werte zur Befüllung entnimmt Ansible dem Konfigurationsparameter vhosts, der für die Rolle webserver angegeben wurde (vorheriges Listing). Mittels with_items: vhosts iteriert das Tool durch alle Einträge und führt den template-Befehl für jeden davon aus. Über die Variable item wird auf den aktuellen Inhalt zugegriffen (ähnlich foreach in PHP). Hier wird daraus der Dateiname der Vhost-Konfiguration bestimmt. Auch innerhalb des Templates sind diese Daten verfügbar.

Damit ist die Konfiguration des Hosts backend fertig. Um Ansible mit dem Playbook provision.yml auszuführen, wird noch das Inventory benötigt. Inventory-Dateien beschreiben, welche realen Maschinen denn eigentlich aufgesetzt werden sollen:

[backend] 
33.33.33.42 # …

Für jede Hostgruppe können hier beliebig viele Einträge konfiguriert werden, es können also mehrere Server als backend eingeteilt werden, die dann von Ansible alle nach den entsprechenden Regieanweisungen aufgesetzt werden. Im Beispiel wird nur ein Host definiert, der eine virtuelle Maschine ist. In Kombination mit Vagrant lassen sich so Entwicklungsmaschinen vollautomatisch einrichten. Der Befehl ansible-playbook -i inventory/vagrant provision.yml instruiert Ansible, das angegebene Playbook auszuführen. Dafür verbindet sich das Tool per SSH parallel auf die im Inventory angegebenen Server und führt alle notwendigen Änderungen aus. Auf den Hosts muss dafür vorab nur ein SSH Daemon und Python installiert sein, ein Puppet-Agent oder Chef-Client ist nicht nötig. Mithilfe von Inventory-Dateien lassen sich also unterschiedliche Umgebungen konfigurieren: Im gezeigten Beispiel wird eine Entwickler-VM verwaltet, denkbar sind weitere Inventories für Staging-Umgebung, CI-Server und Produktion. Durch die Playbooks wird sichergestellt, dass alle diese Umgebungen gleich aussehen. Daneben lässt sich Ansible auch für das Aufsetzen lokaler Maschinen, zum Beispiel Ihres Notebooks, verwenden.

Ansible geht einen pragmatischen Weg zur Orchestrierung und Administration von Hosts. Im Gegensatz zu Konkurrenten wie Puppet ist die Konfiguration leichter verständlich – auch weil die Ausführung sequenziell ist und von oben nach unten gelesen werden kann. Diesen Vorteil erkauft sich Ansible allerdings damit, dass Abhängigkeiten zwischen Tasks und zwischen Services von Hand gemanagt werden müssen. Das ist aber in vielen Fällen gar nicht so schwierig und die Übersichtlichkeit von Ansible trägt viel zum einfachen Einstieg in die Automatisierung bei. Dennoch ist das erstmalige Automatisieren der Projektumgebungen kein Zuckerschlecken und ohne fachkundige Hilfe müssen auf der Fahrt zu einheitlichen Systemen viele Klippen umschifft werden. Einmal geschafft, zeigt sich, dass sich der Aufwand aber auf jeden Fall gelohnt hat.

Unsere Redaktion empfiehlt:

Relevante Beiträge

Meinungen zu diesem Beitrag

X
- Gib Deinen Standort ein -
- or -