Server-Management leicht gemacht: IT-Automation mit Ansible
Wer in einem Unternehmen zahlreiche Server verwalten und häufig deren Konfiguration anpassen muss, braucht Werkzeuge, die bei diesen Aufgaben unterstützen. Mit Hilfe von Configuration-Management(CM)-Systemen verwalten Administratoren die Konfiguration ihrer Infrastruktur – also etwa, welche Pakete auf einem Server installiert sind oder welche Inhalte bestimmte Konfigurationsdateien haben – vollständig in Form von Code. So können sie die Konfiguration eines Systems in Versionskontrollsystemen wie Git speichern und deren Vorteile nutzen: Änderungen lassen sich anhand der Versionsgeschichte jederzeit nachvollziehen, Code Reviews sind möglich oder – über Continuous-Integration-Workflows – automatisierte Tests und Auslieferungen.
Neben Platzhirschen wie Puppet oder Chef hat sich zuletzt Ansible aufgrund seines leichten Einstiegs durchgesetzt. Im Unterschied zu Shell-Skripten, die imperativ beschreiben, wie ein Server zu installieren ist, gehen moderne CM-Systeme wie Puppet, Chef oder auch Ansible bei der Zustandsbeschreibung deklarativ vor. Das CM-System erkennt automatisch den aktuellen Ist-Zustand eines Systems und versucht selbständig den beschriebenen Soll-Zustand herzustellen.
Ansible installieren und einrichten
Im Unterschied zu anderen CM-Werkzeugen benötigt Ansible keine weitere Software auf den zu verwaltenden Servern. Der Nutzer muss Ansible lediglich auf dem Rechner installieren, von dem aus er später alle Server verwalten möchte. Das kann ein Arbeitsplatzrechner oder ein eigens dafür abgestellter Server sein.
Ansible ist in Python geschrieben und setzt somit eine funktionierende Python-Installation voraus. Mac- und Linux-Systeme bieten diese bereits standardmäßig. Um eine aktuelle Ansible-Version zu installieren, nutzten Anwender am einfachsten den Python-Paket-Manager „pip“.
Ansible mit „pip“ installieren
sudo apt-get install python-pip sudo pip install ansible
Listing 1
Der Rechner, der Ansible ausführt, muss alle zu verwaltenden Server per SSH erreichen können. Um den Einsatz unsicherer Passwörter zu vermeiden, empfiehlt sich eine passwortlose Authentifizierung über Schlüsselpaare. Mit den folgenden zwei Befehlen können Entwickler ein RSA-Schlüsselpaar mit ausreichender Schlüssellänge erstellen und den öffentlichen Teil des Schlüssels auf einen Server kopieren.
SSH-Schlüssel erstellen und auf Server kopieren
ssh-keygen -t rsa -b 4096 -f my-key ssh-copy-id -i my-key.pub <user>@server
Listing 2
Danach gibt der Admin Ansible alle zu verwaltenden Server an. Im einfachsten Fall geschieht dies über eine sogenannte Inventory-Datei, die alle Server aufführt. Standardmäßig sucht Ansible diese Datei unter dem Pfad /etc/ansible/hosts. Die Server in dieser Datei lassen sich gruppieren und jeweils mit zusätzlichen Variablen definieren.
Web-Server angeben
[webservers] s1000.mydomain.com s1001.mydomain.com ansible_ssh_private_key=/path/to/other/key [databases] db1000.mydomain.com ansible_ssh_port=8022 db1001.mydomain.com
Listing 3
Nun kann man das Ansible-Kommandozeilen-Tool nutzen, um auf den konfigurierten Servern Befehle auszuführen. Zunächst sollten sie die Verbindung mit einem einfachen Befehl testen.
Die Verbindung testen
ansible '*' -m ping
Listing 4
Darüber hinaus lässt sich Ansible nutzen, um einfache Shell-Kommandos auf mehreren Servern gleichzeitig auszuführen.
Shell-Kommandos auf mehreren Servern ausführen
ansible '*' -m shell -a 'apt-get install php'
Listing 5
Das ,*‘ dient dabei als Wildcard-Ausdruck; der Shell-Befehl wird anschließend auf allen Servern ausgeführt, die diesem Ausdruck entsprechen. Mit dem obigen Inventory-File können Anwender beispielsweise auch den Ausdruck ,db*‘ nutzen, um einen Shell-Befehl gezielt auf allen bekannten Datenbank-Servern auszuführen.
Ein erstes Playbook erstellen
Sogenannte Playbooks beschreiben in Ansible den Soll-Zustand eines Systems. Jedes Playbook ist eine YAML-Datei, die alle Schritte (Tasks) in Listenform beschreibt, die zur Einrichtung des Servers notwendig sind. Jeder Task besteht aus einem Namen und einem Modul, das sich über bestimmte Parameter aufrufen lässt.
Folgendes Code-Beispiel enthält einen Task, der sicherstellt, dass zu jedem Zeitpunkt die aktuellste Version (latest) des Apache-Webservers installiert ist. Wessen Server nicht YUM, sondern APT als Paket-Manager nutzt, kann auch das apt-Modul einsetzen.
Aktuelle Version des Apache-Webservers installieren
- name: configure web server hosts: '*' tasks: - name: install apache yum: name=httpd state=latest # alternativ: # apt: name=apache2 state=latest
Listing 6
Das Playbook können User anschließend mit dem Programm ansible-playbook ausführen.
Das Playbook ausführen
ansible-playbook playbook.yml
Listing 7
Ein Playbook führt die in ihm aufgelisteten Tasks in der Reihenfolge aus, in der sie definiert sind. Tasks sind dabei üblicherweise deklarativ – also nicht „Installiere Paket XY“, sondern „Paket XY muss installiert sein“. Ansible stellt dabei auch bei mehrfachen Ausführungen des Playbooks sicher, dass der Server stets den beschriebenen Zustand erfüllt.
Eine weitere häufige Aufgabe der IT-Automation ist es, Konfigurationsdateien diverser Dienste dynamisch zu generieren. Hierzu können Administratoren das Ansible-Modul „template“ verwenden. Dieses erzeugt aus einer Template-Datei, die auf dem lokalen Rechner liegen muss, und verschiedenen Variablen eine Konfigurationsdatei auf dem Server. Die Template-Sprache ist die im Python-Umfeld weit verbreitete Jinja2.
Ein Jinja-Template für eine php.ini-Datei
memory_limit = {{ ansible_memtotal_mb / 16 }}M display_errors = {{ 'on' if host_is_dev else 'off' }}
Listing 8
Die Variable ansible_memtotal_mb befüllt Ansible automatisch. Sie enthält den auf dem Server zur Verfügung stehenden Arbeitsspeicher in MB. Auf diese Weise kann PHP das Speicherlimit automatisch an den auf dem Server zur Verfügung stehenden Arbeitsspeicher anpassen.
Playbook für automatische Arbeitsspeicheranpassung
- name: configure web server hosts: '*' tasks: ... - name: deploy php.ini template: xsrc=templates/php.ini.j2 dest=/etc/php5/php.ini
Listing 9
Sobald Ansible Konfigurationsdateien ändert, muss es häufig zugeordnete Dienste neu starten. Wer PHP als Apache-Modul nutzt, muss zum Beispiel nach einer Änderung der php.ini-Datei den Webserver neu starten. In Ansible lässt sich dies mit sogenannten Handlern abbilden. Das sind spezielle Tasks, die nur ablaufen, wenn bestimmte Tasks zuvor Änderungen vorgenommen haben. Folgendes Playbook startet den Apache-Webserver neu, wenn Ansible zuvor die php.ini-Konfigurationsdatei geändert hat. Wenn das vorige Playbook erneut läuft, sich der Dateiinhalt aber nicht mehr ändert, stößt Ansible auch keinen Neustart der Webserver an.
Ein Handler zum Neustart des Webservers
- name: configure web server hosts: '*' handlers: - name: restart httpd service: name=httpd state=restarted tasks: - name: deploy php.ini template: xsrc=templates/php.ini.j2 dest=/etc/php5/php.ini notify: - restart httpd
Listing 10
Eine ausführliche Dokumentation zum Erstellen von Ansible-Playbooks findet sich hier. Eine vollständige Liste aller möglichen Module gibt es im Module-Bereich von Ansible.
Fertige Rollen mit Ansible Galaxy
Wie in der Software-Entwicklung auch können Entwickler Code, den sie sorgsam entwickelt haben, in anderen CM-Systemen wiederverwenden. Ansible Galaxy ist ein Online-Repository, aus dem Ansible-Nutzer bereits fertig programmierte Playbooks für bestimmte Server-Rollen herunterladen können. Der ansible-galaxy-Befehl lädt beispielsweise ein fertig definiertes Playbook für die Einrichtung eines Elasticsearch-Servers herunter.
Playbook für Elasticsearch-Server herunterladen
sudo ansible-galaxy install debops.elasticsearch
Listing 11
Anschließend können Developer diese Serverrolle in einem Playbook einsetzen.
Playbook für die Konfiguration
- name: configure elasticsearch hosts: '*' roles: - elasticsearch
Listing 12
ansible-galaxy lässt sich auch nutzen, um neue Rollen zu erstellen. Selbst wenn man seinen eigenen Code nicht veröffentlichen möchte, empfiehlt es sich, größere Playbooks via Ansible Galaxy zu modularisieren. Der folgende Befehl mit ansible-galaxy init erstellt beispielsweise eine neue Rolle für einen Webserver.
Eine neue Rolle für einen Webserver
ansible-galaxy init -p roles webserver
Listing 13
Dieser Befehl erstellt ein neues Verzeichnis roles/webserver. Dieses kann eigene Tasks enthalten, die sich aus dem Haupt-Playbook genauso nutzen lassen wie Rollen aus Ansible Galaxy.
Fazit und Ausblick
Mit CM-Werkzeugen wie Ansible können Anwender die Einrichtung, Wartung und Pflege von Serversystemen ausgezeichnet automatisieren. Vor allem in dynamischen Umgebungen, in denen sie Server häufig neu installieren oder anpassen müssen, rechnet sich der Einsatz dieser Tools schnell.
Als grafische Benutzeroberfläche gibt es zudem Ansible Tower. Im Unterschied zu Ansible selbst steht diese jedoch nicht unter einer Open-Source-Lizenz zur Verfügung, sondern schlägt mit mehreren Tausend US-Dollar pro Jahr zu Buche. Im Gegenzug gibt es eine aufgeräumte grafische Benutzeroberfläche mit differenzierter Benutzer- und Rechteverwaltung, sowie eine REST-API, über die sich alle relevanten Vorgänge steuern lassen.
Die quelloffene Version von Ansible spielt vor allem in kleineren Infrastrukturen bis zu einigen Dutzend Servern ihre Stärken aus. Speziell in Infrastrukturen mit mehreren Hundert oder Tausend Servern stößt Ansible jedoch an seine Grenzen. Hier können große Brüder wie Puppet, Chef oder SaltStack trumpfen, die jedoch in ihrer Bedienung wesentlich komplexer sind.