Website-Suche

So führen Sie Verwaltungsvorgänge mit Ansible-Modulen durch


In früheren Tutorials haben wir Ansible vorgestellt und Ansible-Schleifen besprochen. Dieses Mal lernen wir die grundlegende Verwendung einiger Module kennen, die wir in Playbooks verwenden können, um einige der gängigsten Systemadministrationsvorgänge durchzuführen.

In diesem Tutorial lernen Sie:

  • Hinzufügen/Ändern/Entfernen eines Benutzerkontos mit dem Modul "Benutzer"
  • So verwalten Sie Partitionen mit dem Modul "parted"
  • So führen Sie einen Befehl mit den Modulen "shell" oder "command" aus
  • Kopieren von Dateien oder Schreiben von Dateiinhalten mit dem Modul "Kopieren"
  • So verwalten Sie Dateizeilen mit dem Modul "lineinfile"

Verwendete Softwareanforderungen und Konventionen

Verwalten von Benutzerkonten mit dem Modul "Benutzer"

Wenn wir Ansible für die Bereitstellung verwenden und Benutzerkonten in unseren Playbooks verwalten möchten, können wir das ansible.builtin.user-Modul verwenden, das, wie der vollständige Name schon sagt, Teil der Ansible-Kernmodule ist. Sehen wir uns einige Beispiele für seine Verwendung an.

Erstellen und Ändern eines Benutzerkontos

Angenommen, wir möchten eine Aufgabe erstellen, bei der wir deklarieren, dass der Benutzer "foo" auf dem/den Zielhost(s) existieren sollte und Teil der wheel-Gruppe sein sollte, um sudo verwenden zu können. Hier ist die Aufgabe, die wir in unser Playbook schreiben würden:

- name: Create user foo
  ansible.builtin.user:
    name: foo
    groups: wheel
    password: $6$qMDw5pdZsXt4slFl$V4RzUfqHMgSOtqpdwEeDSCZ31tfBYfiCrEfDHWyjUUEdCy7xnWpnbK54ZxpvO88n1k6EsaE0axpZQgDqkljsp0

Schauen wir uns an, was wir oben getan haben. Die Parameter des ansible.builtin.user-Moduls, die wir verwendet haben, sind: Name, Gruppen und Passwort. Mit der ersten haben wir den Namen des Benutzers deklariert, der erstellt werden soll, mit der zweiten haben wir die zusätzliche(n) Gruppe(n) übergeben, in der der Benutzer Mitglied sein soll. Schließlich haben wir mit dem password-Parameter das Passwort des Benutzers in verschlüsselter Form angegeben. Es ist wichtig zu sagen, dass es nie eine gute Praxis ist, Passwörter direkt in Dateien zu speichern, selbst wenn sie verschlüsselt sind.

Eine andere Sache, die zu beachten ist, ist, dass, wenn die Aufgabe beispielsweise auf einem System ausgeführt wird, auf dem der Benutzer "foo" bereits existiert und er Mitglied anderer zusätzlicher Gruppen ist, er aus diesen entfernt wird, so dass er am Ende der Aufgabe nur Mitglied der "Rad" -Aufgabe ist. Dies ist für den deklarativen Charakter von Ansible. In Aufgaben deklarieren wir Zustände, keine Aktionen, und Ansible führt die notwendigen Schritte aus, um diese Zustände auf den Zielcomputern zu erreichen. Wenn wir möchten, dass der Benutzer seine zusätzliche Gruppenmitgliedschaft beibehält, müssen wir einen anderen Parameter verwenden: append und yes als Wert. So würden wir unsere Aufgabe ändern:

- name: Create user foo
  ansible.builtin.user:
    name: foo
    groups: wheel
    password: $6$qMDw5pdZsXt4slFl$V4RzUfqHMgSOtqpdwEeDSCZ31tfBYfiCrEfDHWyjUUEdCy7xnWpnbK54ZxpvO88n1k6EsaE0axpZQgDqkljsp0
    append: yes

Um den Status eines bestehenden Benutzerkontos zu ändern, müssen wir lediglich den Wert der entsprechenden Parameter ändern. Ansible kümmert sich um die Durchführung der Aktionen, die zum Erreichen der deklarierten Zustände erforderlich sind.

Entfernen eines Benutzerkontos

Das Entfernen eines Benutzers mit dem ansible.builtin.user-Modul ist einfach. Alles, was wir tun müssen, ist zu deklarieren, dass das Benutzerkonto auf dem/den Zielsystem(en) nicht existieren soll. Um dies zu tun, verwenden wir die staatliche Direktive und übergeben ihr den fehlenden Wert:

- name: Remove the foo user
  ansible.builtin.user:
    name: foo
    state: absent

Die obige Aufgabe stellt sicher, dass das Benutzerkonto auf dem Zielsystem nicht vorhanden ist, entfernt jedoch keine Verzeichnisse, die ihm zugeordnet sind. Wenn wir dies erreichen wollen, müssen wir die remove-Direktive hinzufügen und den booleschen Wert yes an sie übergeben:

- name: Remove the foo user
  ansible.builtin.user:
    name: foo
    state: absent
    remove: yes

Verwalten von Partitionen mit dem Modul "parted"

Eine weitere sehr häufige Operation ist das Erstellen und Bearbeiten von Blockgerätepartitionen. Mit Ansible können wir solche Operationen über das Modul community.general.parted durchführen. Sehen wir uns einige Beispiele an. Angenommen, wir möchten eine Partition auf der /dev/sda-Festplatte erstellen. Hier ist, was wir schreiben würden:

- name: Partition /dev/sda
  community.general.parted:
    device: /dev/sda
    number: 1
    state: present

Der erste Parameter, den wir im Beispiel verwendet haben, ist device. Dies ist obligatorisch und wir verwenden es, um anzugeben, auf welcher Festplatte die Aufgabe ausgeführt werden soll. Mit der number-Direktive legen wir fest, welche Partition geändert oder erstellt werden soll. Schließlich erklären wir mit der staatlichen Richtlinie, wie ihr Zustand sein soll. In diesem Fall haben wir "present" als Wert verwendet, so dass die Partition erstellt wird, wenn sie noch nicht existiert.

Festlegen von Partitionsabmessungen

Wie Sie vielleicht bemerkt haben, fehlen in dem Beispiel zwei Dinge: Wir haben nicht angegeben, wo die Partition beginnen und wo sie enden soll. Um den Partitionsoffset anzugeben, müssen wir die Parameter part_start und part_end hinzufügen. Wenn wir dies nicht tun, beginnt die Partition, genau wie im obigen Beispiel, am Anfang der Festplatte (der Standardwert für part_start ist "0%) ") und nimmt den gesamten verfügbaren Speicherplatz auf der Festplatte ein (der Standardwert für part_end ist 100%). Angenommen, wir möchten, dass die Partition bei 1 MiB vom Anfang der Festplatte beginnt und den gesamten verfügbaren Speicherplatz einnimmt. So würden wir unsere Aufgabe ändern:

- name: Create a partition /dev/sda
  community.general.parted:
    device: /dev/sda
    number: 1
    state: present
    part_start: 1MiB

Der Wert, der für den Parameter part_start angegeben wird, kann entweder in Prozentform oder als Zahl angegeben werden, gefolgt von einer der Einheiten, die vom parted-Programm unterstützt werden (MiB, GiB usw.). Wenn der angegebene Wert in negativer Form ist, wird er als Abstand vom Ende der Festplatte betrachtet.

Was ist, wenn wir die Größe einer Partition ändern möchten? Wie bereits erwähnt, arbeitet Ansible deklarativ, sodass wir nur die neue Größe der Partition über die Direktive part_end angeben müssen. Zusätzlich möchten wir den Parameter resize hinzufügen und ihn auf yes setzen. Angenommen, wir möchten die Größe der Partition, die wir im vorherigen Beispiel erstellt haben, auf 50GiB ändern, würden wir schreiben:

- name: Resize the first partition of /dev/sda to 50GiB
  community.general.parted:
    device: /dev/sda
    number: 1
    state: present
    part_end: 50GiB
    resize: yes

Entfernen einer Partition

Um schließlich eine vorhandene Partition zu entfernen, müssen wir lediglich den Parameter state verwenden und ihn auf "abwesend" setzen. Um die Partition zu entfernen, die wir in den vorherigen Beispielen erstellt haben, würden wir schreiben:

- name: Remove the first partition of /dev/sda
  community.general.parted:
    device: /dev/sda
    number: 1
    state: absent

Ausführen von Befehlen mit den Befehls- oder Shell-Modulen

Wie bereits erwähnt, geben wir in den allermeisten Fällen in Ansible-Aufgaben einen bestimmten Zustand an, den wir erhalten möchten, und nicht die spezifischen Befehle, die dazu erforderlich sind. Manchmal möchten wir jedoch einige Befehle explizit ausführen. In diesen Fällen können wir die Module ansible.builtin.command oder ansible.builtin.shell verwenden.

Mit diesen Modulen erreichen wir das gleiche Ziel, funktionieren aber unterschiedlich. Die Befehle, die wir über das Shell-Modul ausführen, werden von einer Shell interpretiert, so dass Variablenerweiterungen und -umleitungen genauso funktionieren, wie sie es tun würden, wenn wir sie manuell starten (manchmal kann dies zu Sicherheitsproblemen führen). Wenn wir das Befehlsmodul verwenden, wird die Shell nicht beteiligt sein, daher ist es die empfohlene Methode, außer in den Fällen, in denen wir speziell Shell-Funktionen benötigen.

Angenommen, wir möchten eine Aufgabe schreiben, um den Neuaufbau des Systems initramfs zu automatisieren. Hier ist, was wir schreiben könnten, angenommen, das System ist Fedora, bei dem die Aktion über den Befehl dracut erreicht wird:

- name: Regenerate initramfs
  ansible.builtin.command:
    cmd: dracut --regenerate-all --force

Im obigen Beispiel haben wir den Befehl als String übergeben. Dies wird als "freie Form" bezeichnet. Befehle können auch als Liste übergeben werden, ähnlich wie wir es tun, wenn wir das Python-Unterprozessmodul verwenden. Wir könnten das Obige mit dem argv-Parameter wie folgt umschreiben:

- name: Regenerate initramfs
  ansible.builtin.command:
    argv:
      - dracut
      - --regenerate-all
      - --force

Wie bereits erwähnt, kann die gleiche Aufgabe mit dem Shell-Modul ausgeführt werden. Auf diese Weise können wir alle Funktionen nutzen, die in der Shell selbst verfügbar sind, wie z.B. Umleitungen. Nehmen wir zum Beispiel an, wir möchten die gleiche Aktion ausführen, aber sowohl den Standardfehler als auch die Standardausgabe des Befehls in die Datei /var/log/log.txt umleiten. Hier ist, was wir schreiben könnten:

- name: Regenerate initramfs and redirect
  ansible.builtin.shell:
    cmd: dracut --regenerate-all --force --verbose &> /var/log/log.txt

Kopieren von Dateien

Wenn wir Ansible-Aufgaben schreiben müssen, um Dateien zu kopieren, können wir das ansible.builtin.copy-Modul verwenden. Die Hauptdirektiven dieses Moduls sind: src und dest. Wie Sie sich vorstellen können, geben wir bei ersterem den Pfad der Datei an, die kopiert werden soll, und bei letzterem den absoluten Pfad, in den sie auf den Zielsystemen kopiert werden soll. Wenn wir einen Verzeichnispfad als Quelle angeben, wird das Verzeichnis selbst mit seinem gesamten Inhalt kopiert, es sei denn, der Pfad endet mit einem Schrägstrich (/). In diesem Fall wird nur der Inhalt des Verzeichnisses kopiert. Angenommen, wir möchten die Datei /foo.conf als /etc/foo.conf auf die Ziel-Hosts kopieren. Wir würden schreiben:

- name: Copy /foo.conf to /etc/foo.conf
  ansible.builtin.copy:
    src: /foo.conf
    dest: /etc/foo.conf

Wir können festlegen, welchen Besitzer und welche Berechtigungen die kopierte Datei auf dem Remote-System haben soll. Dies wird durch die Verwendung der Direktiven owner, group und mode erreicht. Angenommen, wir möchten die kopierte Datei dem Benutzer und der Gruppe "bar" zuweisen, mit 600 als Berechtigungsmodus:

- name: Copy /foo.conf to /etc/foo.conf with specific permissions and owner
  ansible.builtin.copy:
    src: /foo.conf
    dest: /etc/foo.conf
    owner: bar
    group: bar
    mode: 0600

Eine wichtige Sache, die Sie im obigen Beispiel beachten sollten, ist, wie wir den Berechtigungsmodus angegeben haben. Um sicherzustellen, dass sie vom Ansible-YAML-Parser als Oktalzahl geparst wird, haben wir dem Modus eine führende 0 hinzugefügt. Alternativ ist es möglich, den Modus als String zwischen Anführungszeichen zu übergeben oder die symbolische Schreibweise (u=rw) zu verwenden.

Direktes Angeben von Dateiinhalten

Eine interessante Sache, die mit dem Kopiermodul möglich ist, besteht darin, den Inhalt der Zieldatei direkt anzugeben, anstatt eine vorhandene Datei aus der Quelle zu kopieren. Um ein solches Ergebnis zu erzielen, müssen wir die Inhaltsdirektive verwenden. Nehmen wir als Beispiel an, dass die entfernte Datei /etc/foo.conf den Inhalt "Hello World" haben soll (die Datei wird erstellt, wenn sie nicht existiert), wir würden schreiben:

- name: Specify /etc/foo.conf file content
  ansible.builtin.copy:
    dest: /etc/foo.conf
    content: "Hello World\n"

Verwalten von Dateizeilen mit dem Modul "lineinfile"

Um Dateizeilen zu manipulieren, können wir das Modul ansible.builtin.lineinfile verwenden. Sehen wir uns einige Beispiele für seine Verwendung an. Stellen Sie sich vor, die Datei /etc/foo.conf enthält die folgenden Zeilen:

one
two
three
four

Nehmen wir nun an, wir möchten die Zeile entfernen, die mit dem Wort "vier" beginnt. Wir würden schreiben:

- name: Ensure the lines starting with the word "four" don't exist in /etc/foo.conf
  ansible.builtin.lineinfile:
    path: /etc/foo.conf
    regexp: ^four
    state: absent

Mit dem path-Parameter haben wir den Pfad der entfernten Datei angegeben, in der die Aktion stattfinden soll. Der Parameter regexp wird stattdessen verwendet, um den regulären Ausdruck zu übergeben, der dem Muster in den Zeile(n) entsprechen sollte, mit denen wir arbeiten möchten. In diesem Fall haben wir einen regulären Ausdruck übergeben, der auf alle Zeilen passt, die mit dem Wort "vier" beginnen; Sie werden alle entfernt, da wir "abwesend" als Wert des Zustandsparameters übergeben haben.

Angenommen, wir möchten die Zeile, die mit "vier " beginnt, durch einen anderen Inhalt ersetzen, stattdessen vielleicht mit: "von Aufgabe gelöscht ". Um das Ergebnis zu erzielen, verwenden wir den Parameter line:

- name: Substitute  "four" with "deleted by task" in /etc/foo.conf
  ansible.builtin.lineinfile:
    path: /etc/foo.conf
    regexp: ^four
    line: "deleted by task"

Was ist, wenn die Datei mehr als eine Zeile mit einer Übereinstimmung enthält? In den Fällen, in denen der Wert des Parameters state "present" (Standardeinstellung) ist, erfolgt die Ersetzung nur in der letzten übereinstimmenden Zeile.

Schlüsse

In diesem Artikel haben wir gesehen, wie Sie einige gängige Systemadministrationsaufgaben wie die Verwaltung von Benutzerkonten und Partitionen, das Ausführen von Befehlen, das Kopieren von Dateien und das Ändern ihrer Zeilen mit Ansible unter Verwendung der entsprechenden Module ausführen können. Dies war nicht als erschöpfender Leitfaden gedacht, da wir nur die sehr grundlegenden Funktionen der von uns erwähnten Module untersucht haben. Für einen vollständigen Überblick über sie können Sie die offizielle Moduldokumentation konsultieren.

Verwandte Artikel: