Einführung
Zusammengefasst ist die Serverkonfigurationsverwaltung (auch als IT-Automatisierung bezeichnet) eine Lösung, um Ihre Infrastrukturverwaltung in eine Codebasis umzuwandeln, die alle für die Bereitstellung eines Servers erforderlichen Prozesse beschreibt. Diese werden in einer Reihe von Bereitstellungsskripten dargestellt, die versioniert und leicht wiederverwendet werden können. Sie kann die Integrität jeder Serverinfrastruktur im Laufe der Zeit erheblich verbessern.
In einem vorherigen Leitfaden haben wir über die Hauptvorteile der Implementierung einer Konfigurationsverwaltungsstrategie für Ihre Serverinfrastruktur gesprochen, wie Konfigurationsverwaltungstools funktionieren und welche Funktionen diese Tools typischerweise gemeinsam haben.
In diesem Teil der Serie werden wir Sie durch den Prozess der Automatisierung der Serverbereitstellung mithilfe von Ansible führen, einem Konfigurationsverwaltungstool, das einen vollständigen Automatisierungsrahmen und Orchestrierungsfähigkeiten bietet, während es das Ziel ultimativer Einfachheit und Minimalismus beibehält. Wir werden uns auf die Sprachterminologie, Syntax und Funktionen konzentrieren, die für die Erstellung eines vereinfachten Beispiels zur vollständigen Automatisierung der Bereitstellung eines Ubuntu 18.04-Web-Servers mit Apache erforderlich sind.
Die folgende Liste enthält alle Schritte, die wir automatisieren müssen, um unser Ziel zu erreichen:
- Das
apt
-Cache aktualisieren - Apache installieren
- Einen benutzerdefinierten Dokumentstammverzeichnis erstellen
- Platzieren Sie eine
index.html
-Datei im benutzerdefinierten Dokumentenstamm - Wenden Sie eine Vorlage an, um unseren benutzerdefinierten virtuellen Host einzurichten
- Starten Sie Apache neu
Zuerst werfen wir einen Blick auf die von Ansible verwendete Terminologie, gefolgt von einer Übersicht über die Hauptfunktionen der Sprache, die zum Schreiben von Playbooks verwendet werden können. Am Ende des Leitfadens finden Sie den Inhalt eines vollständigen Bereitstellungsbeispiels, um die beschriebenen Schritte zur Einrichtung von Apache unter Ubuntu 18.04 zu automatisieren.
Hinweis: Dieser Leitfaden soll Sie mit der Ansible-Sprache vertraut machen und Ihnen zeigen, wie Sie Playbooks schreiben können, um Ihre Serverbereitstellung zu automatisieren. Für einen einführenderen Blick auf Ansible, einschließlich der Schritte, die für die Installation und den Einstieg in dieses Tool erforderlich sind, sowie Informationen zum Ausführen von Ansible-Befehlen und Playbooks, lesen Sie unseren Leitfaden „Wie man Ansible unter Ubuntu 18.04 installiert und konfiguriert“.
Erste Schritte
Bevor wir uns einen praxisnäheren Blick auf Ansible werfen können, ist es wichtig, dass wir uns mit wichtigen Terminologie und Konzepten vertraut machen, die von diesem Tool eingeführt wurden.
Terminologie
Die folgende Liste enthält einen schnellen Überblick über die wichtigsten Begriffe, die von Ansible verwendet werden:
- Control Node: Die Maschine, auf der Ansible installiert ist und die für die Ausführung der Bereitstellung auf den von Ihnen verwalteten Servern verantwortlich ist.
- Inventar: Eine
INI
-Datei, die Informationen über die von Ihnen verwalteten Server enthält. - Playbook: Eine
YAML
-Datei, die eine Reihe von Verfahren enthält, die automatisiert werden sollen. - Aufgabe: Ein Block, der ein einzelnes Verfahren definiert, das ausgeführt werden soll, z. B.: Installation eines Pakets.
- Modul: Ein Modul abstrahiert typischerweise eine Systemaufgabe, wie den Umgang mit Paketen oder das Erstellen und Ändern von Dateien. Ansible verfügt über eine Vielzahl von integrierten Modulen, aber Sie können auch benutzerdefinierte erstellen.
- Rolle: Ein Satz von verwandten Playbooks, Vorlagen und anderen Dateien, die in einer vordefinierten Weise organisiert sind, um die Wiederverwendung und Weitergabe zu erleichtern.
- Play: Eine Bereitstellung, die von Anfang bis Ende ausgeführt wird, wird als Spiel bezeichnet.
- Fakten: Globale Variablen, die Informationen über das System enthalten, wie Netzwerkschnittstellen oder Betriebssystem.
- Handler: Werden verwendet, um Änderungen am Servicestatus auszulösen, wie das Neustarten oder Neu laden eines Dienstes.
Aufgabenformat
A task defines a single automated step that should be executed by Ansible. It typically involves the usage of a module or the execution of a raw command. This is how a task looks:
- name: This is a task
apt: name=vim state=latest
Der name
-Teil ist eigentlich optional, aber empfohlen, da er im Ausgabebereich der Bereitstellung angezeigt wird, wenn die Aufgabe ausgeführt wird. Der apt
-Teil ist ein integriertes Ansible-Modul, das das Management von Paketen auf Debian-basierten Distributionen abstrahiert. Diese Beispiel-Aufgabe teilt Ansible mit, dass das Paket vim
seinen Zustand auf latest
geändert haben soll, was dazu führt, dass der Paketmanager dieses Paket installiert, falls es noch nicht installiert ist.
Playbook-Format
Playbooks sind YAML
-Dateien, die eine Reihe von Anweisungen zur Automatisierung der Bereitstellung eines Servers enthalten. Das folgende Beispiel ist ein einfaches Playbook, das zwei Aufgaben ausführt: Es aktualisiert den apt
-Cache und installiert anschließend vim
:
---
- hosts: all
become: true
tasks:
- name: Update apt-cache
apt: update_cache=yes
- name: Install Vim
apt: name=vim state=latest
YAML
verwendet Einrückungen, um Datenstrukturen zu serialisieren. Aus diesem Grund müssen Sie beim Schreiben von Playbooks und insbesondere beim Kopieren von Beispielen besonders darauf achten, die richtige Einrückung beizubehalten.
Bevor wir das Ende dieses Leitfadens erreichen, werden wir ein praxisnäheres Beispiel für ein Playbook sehen, das ausführlich erklärt wird. Der nächste Abschnitt gibt einen Überblick über die wichtigsten Elemente und Funktionen, die zum Schreiben von Ansible-Playbooks verwendet werden können.
Das Schreiben von Playbooks
Nun, da Sie mit den grundlegenden Terminologien und dem allgemeinen Format von Playbooks und Aufgaben in Ansible vertraut sind, werden wir einige Funktionen von Playbooks kennenlernen, die uns dabei helfen können, vielseitigere Automatisierungen zu erstellen.
Arbeiten mit Variablen
Es gibt verschiedene Möglichkeiten, Variablen in Ansible zu definieren. Der einfachste Weg besteht darin, den vars
-Abschnitt eines Playbooks zu verwenden. Das folgende Beispiel definiert eine Variable package
, die später innerhalb einer Aufgabe verwendet wird:
---
- hosts: all
become: true
vars:
package: vim
tasks:
- name: Install Package
apt: name={{ package }} state=latest
Die Variable package
hat einen globalen Gültigkeitsbereich, was bedeutet, dass sie von jedem Punkt der Bereitstellung aus abgerufen werden kann, auch von eingebundenen Dateien und Vorlagen.
Verwendung von Schleifen
Schleifen werden typischerweise verwendet, um eine Aufgabe mit verschiedenen Eingabewerten zu wiederholen. Anstatt beispielsweise 10 Aufgaben zum Installieren von 10 verschiedenen Paketen zu erstellen, können Sie eine einzelne Aufgabe erstellen und eine Schleife verwenden, um die Aufgabe mit allen verschiedenen Paketen zu wiederholen, die Sie installieren möchten.
Um eine Schleife innerhalb einer Aufgabe zu erstellen, fügen Sie die Option with_items
mit einem Array von Werten hinzu. Der Inhalt kann über die Schleifenvariable item
abgerufen werden, wie im folgenden Beispiel gezeigt:
- name: Install Packages
apt: name={{ item }} state=latest
with_items:
- vim
- git
- curl
Sie können auch eine Array-Variable verwenden, um Ihre Elemente zu definieren:
---
- hosts: all
become: true
vars:
packages: [ 'vim', 'git', 'curl' ]
tasks:
- name: Install Package
apt: name={{ item }} state=latest
with_items: "{{ packages }}"
Verwendung von Bedingungen
Bedingungen können verwendet werden, um dynamisch zu entscheiden, ob eine Aufgabe ausgeführt werden soll oder nicht, basierend auf einer Variablen oder einer Ausgabe aus einem Befehl, zum Beispiel.
Das folgende Beispiel wird nur Debian-basierte Systeme herunterfahren:
Die Bedingung when
erhält als Argument einen Ausdruck, der ausgewertet werden soll. Die Aufgabe wird nur ausgeführt, wenn der Ausdruck als true
ausgewertet wird. In unserem Beispiel haben wir eine Tatsache getestet, um zu überprüfen, ob das Betriebssystem aus der Debian-Familie stammt.
A common use case for conditionals in IT automation is when the execution of a task depends on the output of a command. With Ansible, the way we implement this is by registering a variable to hold the results of a command execution, and then testing this variable in a subsequent task. We can test for the command’s exit status (if failed or successful). We can also check for specific contents inside the output, although this might require the usage of regex expressions and string parsing commands.
Im nächsten Beispiel werden zwei bedingte Aufgaben basierend auf der Ausgabe eines php -v
-Befehls gezeigt. Wir werden den Exit-Status des Befehls testen, da wir wissen, dass er fehlschlagen wird, wenn PHP nicht auf diesem Server installiert ist. Der Teil ignore_errors
der Aufgabe ist wichtig, um sicherzustellen, dass die Bereitstellung fortgesetzt wird, auch wenn der Befehl nicht erfolgreich ausgeführt wird.
Das hier verwendete debug
-Modul ist ein nützliches Modul zum Anzeigen von Inhalten von Variablen oder Debug-Nachrichten. Es kann entweder einen String ausgeben (wenn das msg
-Argument verwendet wird) oder den Inhalt einer Variablen ausgeben (wenn das var
-Argument verwendet wird).
Arbeiten mit Vorlagen
Vorlagen werden typischerweise verwendet, um Konfigurationsdateien einzurichten, die die Verwendung von Variablen und anderen Funktionen ermöglichen, um diese Dateien vielseitiger und wiederverwendbarer zu machen. Ansible verwendet den Jinja2-Vorlagenmotor.
Das folgende Beispiel ist eine Vorlage zur Einrichtung eines Apache-Virtualhosts, wobei eine Variable für die Einrichtung des Dokumentroots für diesen Host verwendet wird:
<VirtualHost *:80>
ServerAdmin webmaster@localhost
DocumentRoot {{ doc_root }}
<Directory {{ doc_root }}>
AllowOverride All
Require all granted
</Directory>
</VirtualHost>
Das integrierte Modul template
wird verwendet, um die Vorlage aus einer Aufgabe anzuwenden. Wenn Sie die oben genannte Vorlagendatei vhost.tpl
benannt und sie im selben Verzeichnis wie Ihr Playbook platziert haben, ist dies, wie Sie die Vorlage anwenden würden, um den Standard-Apache-Virtualhost zu ersetzen:
Definition und Auslösung von Handlern
Handler werden verwendet, um einen Zustandswechsel in einem Dienst auszulösen, wie z.B. ein Neustart oder ein Stoppen. Obwohl sie ähnlich wie normale Aufgaben aussehen mögen, werden Handler nur ausgeführt, wenn sie zuvor durch eine notify
-Anweisung in einer Aufgabe ausgelöst wurden. Sie werden typischerweise als Array in einem handlers
-Abschnitt des Playbooks definiert, können aber auch in separaten Dateien stehen.
Lassen Sie uns unser vorheriges Beispiel für die Verwendung von Vorlagen betrachten, bei dem wir einen Apache-Virtualhost einrichten. Wenn Sie sicherstellen möchten, dass Apache nach einer Änderung am Virtualhost neu gestartet wird, müssen Sie zunächst einen Handler für den Apache-Dienst erstellen. So werden Handler innerhalb eines Playbooks definiert:
Die name
-Direktive hier ist wichtig, weil sie der eindeutige Bezeichner dieses Handlers sein wird. Um diesen Handler von einer Aufgabe aus zu aktivieren, sollten Sie die notify
-Option verwenden:
Wir haben einige der wichtigsten Funktionen gesehen, die Sie verwenden können, um mit dem Schreiben von Ansible-Playbooks zu beginnen. Im nächsten Abschnitt werden wir uns ein praxisnäheres Beispiel eines Playbooks ansehen, das die Installation und Konfiguration von Apache auf Ubuntu automatisieren wird.
Beispiel-Playbook
Werfen wir nun einen Blick auf ein Playbook, das die Installation eines Apache-Web-Servers auf einem Ubuntu 18.04-System automatisiert, wie in der Einführung zu diesem Leitfaden besprochen.
Das vollständige Beispiel, einschließlich der Vorlagendatei zum Einrichten von Apache und einer HTML-Datei, die vom Webserver bereitgestellt werden soll, finden Sie auf Github. Der Ordner enthält auch eine Vagrantfile, mit der Sie das Playbook in einem vereinfachten Setup testen können, das eine virtuelle Maschine verwendet, die von Vagrant verwaltet wird.
Inhalte des Playbooks
Der vollständige Inhalt des Playbooks steht hier zur Verfügung, um ihn bequem durchzusehen:
- ---
- - hosts: all
- become: true
- vars:
- doc_root: /var/www/example
- tasks:
- - name: Update apt
- apt: update_cache=yes
-
- - name: Install Apache
- apt: name=apache2 state=latest
-
- - name: Create custom document root
- file: path={{ doc_root }} state=directory owner=www-data group=www-data
-
- - name: Set up HTML file
- copy: src=index.html dest={{ doc_root }}/index.html owner=www-data group=www-data mode=0644
-
- - name: Set up Apache virtual host file
- template: src=vhost.tpl dest=/etc/apache2/sites-available/000-default.conf
- notify: restart apache
- handlers:
- - name: restart apache
- service: name=apache2 state=restarted
-
Lassen Sie uns jeden Abschnitt dieses Playbooks genauer untersuchen:
hosts: all
Das Playbook beginnt damit zu erklären, dass es auf alle
Hosts in Ihrem Inventar angewendet werden sollte (hosts: all
). Es ist möglich, die Ausführung des Playbooks auf einen bestimmten Host oder eine Gruppe von Hosts zu beschränken. Diese Option kann zur Ausführungszeit überschrieben werden.
become: true
Der Teil become: true
fordert Ansible auf, bei der Ausführung aller Aufgaben in diesem Playbook eine Privilegien-Eskalation (sudo) zu verwenden. Diese Option kann auf Task-Ebene überschrieben werden.
vars
Definiert eine Variable, doc_root
, die später in einer Aufgabe verwendet wird. Dieser Abschnitt kann mehrere Variablen enthalten.
tasks
Der Abschnitt, in dem die tatsächlichen Aufgaben definiert sind. Die erste Aufgabe aktualisiert den apt
-Cache, und die zweite Aufgabe installiert das Paket apache2
.
Die dritte Aufgabe verwendet das integrierte Modul file, um ein Verzeichnis zu erstellen, das als unser Dokumentenstamm dienen soll. Mit diesem Modul können Dateien und Verzeichnisse verwaltet werden.
Die vierte Aufgabe verwendet das Modul copy, um eine lokale Datei auf den Remote-Server zu kopieren. Wir kopieren eine einfache HTML-Datei, die als unsere von Apache gehostete Website dienen soll.
handlers
Schließlich haben wir den Abschnitt handlers
, in dem die Services deklariert sind. Wir definieren den Handler restart apache
, der von der vierten Aufgabe benachrichtigt wird, in der die Apache-Vorlage angewendet wird.
Ausführen eines Playbooks
Nachdem Sie den Inhalt dieses Playbooks auf Ihren Ansible-Steuerknoten heruntergeladen haben, können Sie ansible-playbook
verwenden, um es auf einem oder mehreren Knoten aus Ihrem Inventar auszuführen. Der folgende Befehl führt das Playbook auf allen Hosts aus Ihrer Standardinventardatei aus und verwendet die SSH-Schlüsselpaar-Authentifizierung, um sich als aktueller Systembenutzer zu verbinden:
Sie können auch -l
verwenden, um die Ausführung auf einen einzelnen Host oder eine Gruppe von Hosts aus Ihrem Inventar zu beschränken:
Wenn Sie einen anderen SSH-Benutzer angeben müssen, um sich mit dem Remote-Server zu verbinden, können Sie das Argument -u Benutzer
zu diesem Befehl hinzufügen:
Weitere Informationen zum Ausführen von Ansible-Befehlen und Playbooks finden Sie in unserem Leitfaden „Wie man Ansible unter Ubuntu 18.04 installiert und konfiguriert“.
Zusammenfassung
Ansible ist ein minimalistisches IT-Automatisierungstool mit einer geringen Lernkurve, das YAML
für seine Bereitstellungsskripte verwendet. Es verfügt über eine Vielzahl von integrierten Modulen, die verwendet werden können, um Aufgaben wie die Installation von Paketen und die Arbeit mit Vorlagen abstrakt darzustellen. Seine vereinfachten Infrastrukturanforderungen und die einfache Sprache können gut für diejenigen geeignet sein, die mit der Konfigurationsverwaltung beginnen. Es könnte jedoch einige fortgeschrittene Funktionen fehlen, die Sie bei komplexeren Tools wie Puppet und Chef finden können.
In dem nächsten Teil dieser Serie werden wir einen praktischen Überblick über Puppet sehen, ein beliebtes und etabliertes Konfigurationsverwaltungstool, das eine ausdrucksstarke und leistungsstarke benutzerdefinierte DSL auf Ruby-Basis verwendet, um Bereitstellungsskripte zu schreiben.