Ansible unter Ubuntu 22.04 installieren und konfigurieren

Ansible ist ein sehr beliebtes Konfigurationsmanagement-Tool, das die Steuerung einer großen Anzahl von Servern vereinfacht. Es kann die Einrichtung neuer Server und die Installation von Anwendungen mit einem einzigen Befehl oder einer einzigen Datei automatisieren. Du kannst von einem einzigen Knotenpunkt aus beliebig viele Server steuern und Prozesse auf ihnen gleichzeitig ausführen. Ansible erfordert keine spezielle Software, die auf den Serverknoten installiert werden muss, und kann sie über SSH steuern.

In dieser Anleitung lernen wir, wie man Ansible auf einem Ubuntu 22.04 Server installiert und konfiguriert.

Voraussetzungen

  • Zwei oder mehr Serversysteme mit Ubuntu 22.04 und installiertem OpenSSH-Server.
  • Sowohl der Server als auch die Nodes sind über öffentliche IP-Adressen erreichbar.
  • Auf dem Ansible-Server ist ein Nicht-Root-Benutzer mit sudo-Rechten eingerichtet und auf den Ansible-Clients ist ein Root-Benutzer mit einem Passwort eingerichtet.

Schritt 1 – Ansible installieren

Wir werden das offizielle Repository von Ansible nutzen, um die neueste Version zu installieren. Füge das offizielle Repository von Ansible auf dem Server hinzu.

$ sudo add-apt-repository ppa:ansible/ansible

Zum Glück wird Ubuntu mit Ansible 2.9 ausgeliefert, das wir installieren werden. Führe den folgenden Befehl aus, um Ansible zu installieren.

$ sudo apt install ansible -y

Teste deine Installation, indem du den folgenden Befehl ausführst.

$ ansible --version
ansible [core 2.13.3rc1]
  config file = /etc/ansible/ansible.cfg
  configured module search path = ['/home/navjot/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python3/dist-packages/ansible
  ansible collection location = /home/navjot/.ansible/collections:/usr/share/ansible/collections
  executable location = /usr/bin/ansible
  python version = 3.10.4 (main, Jun 29 2022, 12:14:53) [GCC 11.2.0]
  jinja version = 3.0.3
  libyaml = True

Installiere und aktiviere das Paket python3-argcomplete, um die Unterstützung für die Bash-Vervollständigung von Ansible einzurichten.

$ sudo apt install python3-argcomplete
$ sudo activate-global-python-argcomplete3

Du kannst jetzt die Tabulatortaste drücken, um eine Liste mit Optionen für die Bash-Shell zu erhalten.

Schritt 2 – Einrichten der Inventarisierungsdatei

Damit du dich mit mehreren Hosts verbinden kannst, brauchst du eine Datei, in der die Details der Knoten festgehalten werden. Diese Datei wird Inventory File genannt.

Je nachdem, wie viele Server du kontrollieren willst, kannst du sie in der Inventory-Datei von Ansible auch in Gruppen und Untergruppen einteilen. Du kannst auch benutzerdefinierte Variablen für bestimmte Hosts oder Gruppen festlegen, die bei der Weitergabe der Anweisungen weiter verwendet werden können.

Ansible wird mit einer Standard-Inventardatei ausgeliefert, die du unter /etc/ansible/hosts findest. Öffne sie mit dem Nano-Editor.

$ sudo nano /etc/ansible/hosts

Füge den folgenden Code am Ende der Datei ein.

[servers]
server1 ansible_host=203.0.113.111
server2 ansible_host=203.0.113.112
server3 ansible_host=203.0.113.113

[all:vars]
ansible_python_interpreter=/usr/bin/python3

Der Abschnitt servers definiert die Liste der Knoten, mit denen du dich verbinden willst. Du kannst beliebig viele Gruppen erstellen, um Server in mehreren Gruppen anzuordnen.

Die Gruppe all:vars setzt den Parameter ansible_python_interpreter auf allen Hosts im Inventar. Sie stellt sicher, dass Ansible die ausführbare Datei Python 3 verwendet und nicht Python 2, das aus den letzten Ubuntu-Versionen entfernt wurde.

Wenn du fertig bist, speichere die Datei, indem du Strg + X drückst und Y eingibst, wenn du aufgefordert wirst, deine Änderungen zu bestätigen.

Hinweis: Du kannst deine Inventardatei auch an einem beliebigen Ort deiner Wahl erstellen, den du dann beim Ausführen von Ansible-Befehlen mit dem Parameter -i weitergeben kannst.

Du kannst deine Inventarliste mit dem folgenden Befehl überprüfen.

$ ansible-inventory --list -y
all:
  children:
    servers:
      hosts:
        server1:
          ansible_host: 203.0.113.111
          ansible_python_interpreter: /usr/bin/python3
        server2:
          ansible_host: 203.0.113.112
          ansible_python_interpreter: /usr/bin/python3
        server3:
          ansible_host: 203.0.113.113
          ansible_python_interpreter: /usr/bin/python3
    ungrouped: {}

Organisation von Servern in Gruppen und Untergruppen

Dies ist ein nützlicher Tipp, wenn du viele Server hast, von denen einige bestimmte Funktionen erfüllen. Mit dieser Methode kannst du zum Beispiel Webserver und Datenbankserver getrennt gruppieren. Du kannst sogar einen Host in mehrere Gruppen einteilen. Dazu sollte deine Inventardatei etwa so aussehen wie die folgende.

[webservers]
203.0.113.111
203.0.113.112

[dbservers]
203.0.113.113
server_hostname

[development]
203.0.113.111
203.0.113.113

[production]
203.0.113.112
server_hostname

Schritt 3 – SSH-Schlüssel einrichten

Damit Ansible sich mit den Servern verbinden kann, musst du SSH-Schlüssel zwischen deinem Ansible-Server und den in der Inventardatei angegebenen Hosts einrichten. Das funktioniert nur, wenn die Ansible-Clients keinen öffentlichen Schlüssel und ein Root-Konto mit einem Passwort aktiviert haben.

Gehe wie folgt vor, um einen SSH-Schlüssel für Ansible und seine Knoten zu erstellen und einzurichten.

Erstelle den Schlüssel für Ansible.

$ ssh-keygen -t rsa -b 4096 -C "Ansible key"

Kopiere den öffentlichen Schlüssel auf deine Konten auf den Remote-Servern. Hierfür verwenden wir den Befehl ssh-copy-id.

$ ssh-copy-id -i $HOME/.ssh/id_rsa.pub root@203.0.113.111
$ ssh-copy-id -i $HOME/.ssh/id_rsa.pub root@203.0.113.112
$ ssh-copy-id -i $HOME/.ssh/id_rsa.pub root@203.0.113.113

Das war’s schon. Jetzt sollte Ansible in der Lage sein, mit deinen Servern zu kommunizieren.

SSH-Schlüssel auf Knoten mit vorhandenem öffentlichen Schlüssel einrichten

Wenn auf den Clients bereits öffentliche Schlüssel aktiviert sind, musst du einige zusätzliche Schritte ausführen. Dazu musst du auf jedem Node-Server einen neuen Benutzer anlegen, auf den nur Ansible Zugriff hat. Dieser Benutzer hat sudo-Rechte, die ohne Passwort zugänglich sind, und kann nur von deinem Ansible-Server aus angesprochen werden.

Um einen ansible Benutzer zu erstellen, führe den folgenden Befehl aus.

$ sudo adduser ansible

Wähle ein sicheres Passwort und lasse alle anderen Felder leer.

Konfiguriere nun den passwortlosen sudo-Zugriff für diesen Benutzer mit dem folgenden Befehl.

$ echo "ansible ALL=(ALL) NOPASSWD:ALL" | sudo tee /etc/sudoers.d/ansible

Nachdem du den neuen Benutzer hinzugefügt und konfiguriert hast, kannst du mit dem folgenden Befehl den SSH-Schlüssel von deinem Ansible-Server auf den Node-Server kopieren.

$ ssh-copy-id ansible@203.0.113.111

Du wirst aufgefordert, ein Passwort für den ansible-Benutzer einzugeben. Gib es ein und der SSH-Schlüssel wird kopiert.

Als Nächstes deaktivierst du die passwortbasierte Anmeldung für den Benutzer ansible auf dem Node-Server.

$ sudo usermod -L ansible

Jetzt ist dein Node-Server nur noch vom Ansible-Server aus erreichbar, da nur dieser Server den öffentlichen Schlüssel dafür hat und du ihn nicht direkt mit sudo-Rechten auf dem Node-Server benutzen kannst, da die Passwortanmeldung deaktiviert ist.

Du musst diese Schritte für jeden Node-Server wiederholen. Ersetze außerdem den Benutzer root durch den Benutzer ansible in diesem Tutorial.

Schritt 4 – Verbindung testen

Nachdem wir die Inventardatei und die SSH-Schlüssel eingerichtet haben, sollten wir überprüfen, ob Ansible sich mit den Servern verbinden kann.

Gib den folgenden Befehl ein, um die Verbindung zu prüfen. Mit diesem Befehl wird die Verbindung zu allen Servern aus der Inventardatei getestet.

$ ansible all -m ping -u root

Dieser Befehl verwendet das Ping-Modul von Ansible, um die Verbindung zu allen Servern zu testen. Du solltest eine Ausgabe wie die folgende erhalten.

server1 | SUCCESS => {
    "changed": false,
    "ping": "pong"
}
server2 | SUCCESS => {
    "changed": false,
    "ping": "pong"
}
server3 | SUCCESS => {
    "changed": false,
    "ping": "pong"
}

Wenn du Ansible zum ersten Mal verwendest, wirst du aufgefordert, die Authentizität aller Server zu bestätigen. Wenn du dazu aufgefordert wirst, gib yes ein und drücke zur Bestätigung ENTER.

Schritt 5 – Ausführen einiger grundlegender Befehle

Lass uns mit Ansible einige grundlegende Befehle auf den Servern ausführen. Um einen Befehl auf dem Server auszuführen, wird das folgende Format verwendet.

$ ansible all -a "command" -u <username>

Festplattenauslastung prüfen

Als Erstes überprüfen wir die Festplattennutzung auf allen unseren Servern.

$ ansible all -a "df -h" -u root
server1 | CHANGED | rc=0 >>
Filesystem      Size  Used Avail Use% Mounted on
tmpfs           198M  972K  197M   1% /run
/dev/sda2        50G  3.9G   44G   9% /
tmpfs           989M     0  989M   0% /dev/shm
tmpfs           5.0M     0  5.0M   0% /run/lock
tmpfs           198M  4.0K  198M   1% /run/user/1000

server2 | CHANGED | rc=0 >>
Filesystem      Size  Used Avail Use% Mounted on
tmpfs           198M  922K  197M   1% /run
/dev/sda2        50G  4.9G   43G  10% /
tmpfs           989M     0  989M   0% /dev/shm
tmpfs           5.0M     0  5.0M   0% /run/lock
tmpfs           198M  4.0K  198M   1% /run/user/1000

Einzelne Hosts und Gruppen anvisieren

Bis jetzt haben wir die Befehle auf allen Remote-Servern gleichzeitig ausgeführt. Das ist aber nicht immer der Fall. Um einen Befehl nur auf einem Server auszuführen, solltest du das folgende Format verwenden.

$ ansible server1 -a "uptime" -u root
server1 | CHANGED | rc=0 >>
 21:38:26 up 11 min,  2 users,  load average: 0.00, 0.20, 0.19

Der obige Befehl prüft die Betriebszeit auf Server1 aus der Bestandsgruppe.

Du kannst auch mehrere Server mit folgendem Format abfragen.

$ ansible server1:server2 -m ping -u root

Du kannst auch Gruppen oder Untergruppen direkt aus der Inventardatei ansteuern.

$ ansible groupname -m ping -u <username>

Alle Server aktualisieren

In diesem Tutorial gehen wir davon aus, dass alle entfernten Server mit Debian oder Ubuntu betrieben werden.

Führe den folgenden Befehl aus, um die Software auf all deinen Servern zu aktualisieren.

$ ansible all -m apt -a "update_cache=yes upgrade=yes" -u root

Der Parameter -m definiert das Modul, das Ansible ausführen soll. Der Parameter -a bezieht sich auf die Argumente oder Befehle für das zugehörige Modul. Hier verwenden wir das Modul apt von Ansible, um die Server zu aktualisieren, genauso wie wir das Modul ping in unserem letzten Beispiel verwendet haben. Der update_cache aktualisiert den APT-Cache auf dem Server und upgrade=yes weist Ansible an, den Befehl apt upgrade auszuführen.

Wenn du wie oben beschrieben den Benutzer ansible verwendest, musst du den Befehl ansible so ändern, dass er mit erweiterten sudo-Rechten ausgeführt wird.

$ ansible server2 -m apt -a "update_cache=yes upgrade=yes" -K -b -u ansible

Hier fragt -K nach einem Passwort für die Privilegienerweiterung. -b führt die Ansible-Operation mit become aus, wodurch du ein anderer Benutzer sein kannst. Beide Variablen zusammen ermöglichen es ansible, mit erweiterten sudo-Rechten zu laufen. Du musst dies für alle Befehle verwenden, die sudo-Rechte erfordern.

Manchmal kann es vorkommen, dass einige dieser Update-Befehle einen Neustart erfordern, also führe den folgenden Befehl aus, um alle deine Server neu zu starten.

$ ansible all -a "reboot" -u root

Dies waren nur einige der grundlegenden Befehle, die du mit Ansible ausführen kannst.

Schritt 6 – Einführung in Playbooks

Mit den oben genannten Befehlen kannst du einmalige Aufgaben ausführen. Wenn du jedoch mehrere Server einrichten oder dieselbe Befehlsfolge auf mehreren Servern ausführen willst, musst du Playbooks einrichten. Playbooks sind in YAML geschriebene Dateien, die Anweisungen enthalten, um eine Abfolge von Aufgaben zur Einrichtung von Anwendungen und Diensten zu automatisieren.

Wir werden jetzt ein Playbook erstellen, um Nginx zu installieren und eine HTML-Seite auf dem Ansible-Knoten einzurichten. Erstelle ein Verzeichnis für Ansible in deinem Home-Verzeichnis.

$ mkdir ~/ansible

Erstelle und öffne die Playbook-Datei zur Bearbeitung.

$ cd ~/ansible
$ nano testplaybook.yml

Playbooks verwenden das YAML-Format, um einen oder mehrere Abläufe zu definieren. Ein Play ist eine Reihe von geordneten Aufgaben, die so angeordnet sind, dass ein Prozess automatisiert wird. Die Abläufe werden als YAML-Liste definiert.

Der erste Schritt bei der Definition eines Plays besteht darin, mit der Direktive hosts: all zu bestimmen, welche Hosts das Ziel sind. Die Direktive become wird verwendet, um anzugeben, dass die folgenden Aufgaben von einem Superuser ausgeführt werden müssen.

Wir werden drei Aufgaben definieren: eine, um einen Benutzer hinzuzufügen, eine, um alle Pakete zu aktualisieren, und die letzte, um den Nginx-Server zu installieren. Der Abschnitt vars des Playbooks wird verwendet, um benutzerdefinierte Variablen zu definieren. Wir definieren zwei Variablen, eine für den Benutzer, den wir hinzufügen müssen, und die zweite, um den Status des Pakets zu definieren, das wir installieren müssen. Um die Variable zu verwenden, müssen wir den Variablennamen in doppelte geschweifte Klammern einschließen.

Das Modul ansible.builtin.user wird verwendet, um einen neuen Benutzer mit sudo-Rechten hinzuzufügen. Um den Benutzer hinzuzufügen, verwenden wir die Variablen name, password und group. Die Variable group wird auf sudo gesetzt, um dem Benutzer Superuser-Rechte zu geben. Das Klartext-Passwort kann nicht in die Playbook-Datei aufgenommen werden, daher fügen wir ein SHA-gehashtes Geheimnis hinzu. Hierfür verwenden wir das Dienstprogramm mkpasswd. Um es zu installieren, führe den folgenden Befehl aus, um das Paket whois zu installieren.

$ sudo apt install whois

Erstelle das gehashte Passwort. Du wirst nach dem üblichen Passwort gefragt und erhältst dafür eine gehashte Zeichenfolge. Notiere dir den Hash-Schlüssel, der in der Playbook-Datei verwendet werden soll.

$ mkpasswd --method=sha-512
Password:
$6$dGbprm2oVqClDDDh$Epk6r5eXYkYBaQpQpP.H7VCdz0g9Aj0aO8hjy/WXq4WmfQ7GvQP2/cl/cNhd7.LRFuCKix9uCF2t8X5/Pv0Lk1

Mit der Direktive update_cache aktualisierst du die Repository-Liste des Systems genau wie mit dem Befehl apt update und mit der Direktive upgrade: dist weist du Ansible an, das System-Upgrade durchzuführen. Die dritte Aufgabe ist selbsterklärend und installiert die neueste Version des Nginx-Servers.

Basierend auf den besprochenen Informationen fügst du den folgenden Code in die Datei ein. Füge den Hash-Schlüssel, den du erhalten hast, als Wert für die Variable password ein.

---
- name: Test playbook
  hosts: all
  become: true
  vars:
      state: latest
      user: navjot
  tasks:
  - name: Add the user {{ user }}
    ansible.builtin.user:
      name: "{{ user }}"
      password: '$6$dGbprm2oVqClDDDh$Epk6r5eXYkYBaQpQpP.H7VCdz0g9Aj0aO8hjy/WXq4WmfQ7GvQP2/cl/cNhd7.LRFuCKix9uCF2t8X5/Pv0Lk1'
      group: sudo
  - name: Upgrade all apt packages
    apt:
      update_cache: yes
      upgrade: dist
  - name: Install the {{ state }} of package "nginx"
    apt:
      name: "nginx"
      state: "{{ state }}"

Speichere die Datei, indem du Strg + X drückst und Y eingibst, wenn du aufgefordert wirst, deine Änderungen zu bestätigen.

Um das Playbook auszuführen, führe den folgenden Befehl aus. Das Flag --ask-become-pass fragt dich nach deinem Root-Passwort, um einen erweiterten Vorgang auszuführen.

$ ansible-playbook testplaybook.yml --ask-become-pass

Du erhältst die folgende Ausgabe.

BECOME password:

PLAY [Test playbook] ***************************************************************************************************

TASK [Gathering Facts] *************************************************************************************************
ok: [server1]
ok: [server2]
ok: [server3]

TASK [Add the user casablanca] *****************************************************************************************
changed: [server3]
changed: [server2]
changed: [server1]

TASK [Upgrade all apt packages] ****************************************************************************************
changed: [server1]
changed: [server2]
changed: [server3]

TASK [Install the latest of package "nginx"] ***************************************************************************
changed: [server3]
changed: [server2]
changed: [server1]

PLAY RECAP *************************************************************************************************************
server1                    : ok=4    changed=3    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
server2                    : ok=4    changed=3    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
server3                    : ok=4    changed=3    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

Dies bestätigt, dass dein Playbook erfolgreich ausgeführt wurde.

Wenn du eine benutzerdefinierte Inventardatei verwendest, musst du den Speicherort der Datei wie folgt in den Befehl aufnehmen.

$ ansible-playbook -i /etc/ansible/custominventory testplaybook.yml --ask-become-pass 

Fazit

Damit ist unser Tutorial zur Installation und Konfiguration von Ansible auf einem Ubuntu 22.04 Server beendet. Wenn du Fragen hast, schreibe sie unten in die Kommentare.

Das könnte dich auch interessieren …