Ansible Bedingungen und Schleifen

AnsibleBeginner
Jetzt üben

Einführung

In diesem Lab werden Sie zwei leistungsstarke Funktionen von Ansible kennenlernen: Bedingungen (Conditionals) und Schleifen (Loops). Diese Konzepte ermöglichen es Ihnen, dynamischere und effizientere Playbooks zu erstellen, indem Sie die Task-Ausführung von bestimmten Bedingungen abhängig machen und Aufgaben für mehrere Elemente wiederholen. Am Ende dieses Labs werden Sie verstehen, wie Sie Bedingungen für Entscheidungen in Ihren Playbooks verwenden und wie Sie Schleifen implementieren, um repetitive Aufgaben effizient auszuführen. Dieses Wissen hilft Ihnen dabei, flexiblere und leistungsstärkere Ansible-Playbooks zur Verwaltung Ihrer Infrastruktur zu erstellen.

Einrichten der Umgebung

In diesem Schritt richten Sie die Arbeitsumgebung für die Übungen zu Ansible-Bedingungen und -Schleifen ein. Diese Vorbereitung stellt die Dateien und Verzeichnisse bereit, die in allen nachfolgenden Aufgaben verwendet werden.

Navigieren Sie zunächst zum Projektverzeichnis. Geben Sie dazu im Terminal Folgendes ein:

cd ~/project

Dieser Befehl wechselt Ihr aktuelles Verzeichnis zu ~/project, unserem vorgesehenen Arbeitsbereich für dieses Lab.

Nun erstellen wir eine Inventardatei (Inventory). In Ansible definiert eine Inventardatei die Hosts und Hostgruppen, auf denen Befehle, Module und Tasks in einem Playbook ausgeführt werden. Für dieses Lab verwenden wir ein einfaches Inventar, das nur den localhost enthält.

Erstellen Sie eine neue Datei namens inventory.ini:

nano inventory.ini

Dieser Befehl öffnet den Texteditor Nano. Wenn Sie mit Nano nicht vertraut sind, machen Sie sich keine Sorgen – es ist ein einfacher, benutzerfreundlicher Texteditor. Der Cursor wird in der Datei platziert und wartet auf Ihre Eingabe.

Fügen Sie nun den folgenden Inhalt in die Datei ein:

[local]
localhost ansible_connection=local

Schauen wir uns das genauer an:

  • [local] definiert eine Gruppe namens "local".
  • localhost ist der Name des Hosts.
  • ansible_connection=local weist Ansible an, Befehle lokal anstatt über SSH auszuführen.

Um die Datei zu speichern und Nano zu verlassen, drücken Sie Ctrl+X, dann Y, um den geänderten Puffer zu speichern, und anschließend Enter, um den Dateinamen zu bestätigen.

Als Nächstes erstellen wir ein Verzeichnis für unsere Playbooks:

mkdir playbooks
cd playbooks

Der Befehl mkdir erstellt ein neues Verzeichnis namens "playbooks", und mit cd wechseln wir in dieses neue Verzeichnis.

Warum tun wir das? Die Organisation Ihrer Ansible-Dateien in Verzeichnissen ist eine bewährte Methode (Best Practice). Dadurch bleibt Ihr Projekt übersichtlich, insbesondere wenn es wächst und komplexer wird.

Indem Sie diesen Schritten gefolgt sind, haben Sie nun eine grundlegende Ansible-Umgebung eingerichtet. Sie verfügen über eine Inventardatei, die Ansible sagt, mit welchen Hosts gearbeitet werden soll, und über ein dediziertes Verzeichnis für Ihre Playbooks. Diese Struktur erleichtert die Verwaltung Ihrer Ansible-Projekte, während Sie lernen und mit komplexeren Funktionen experimentieren.

Einführung in Bedingungen

In diesem Schritt verwenden Sie Ansible-Bedingungen, um die Task-Ausführung basierend auf spezifischen Bedingungen zu steuern. Dies ist nützlich, wenn Sie je nach Zustand Ihres Systems oder dem Wert bestimmter Variablen unterschiedliche Aktionen ausführen müssen.

Erstellen wir ein einfaches Playbook, das die Verwendung von Bedingungen demonstriert:

nano conditional_example.yml

Dieser Befehl öffnet den Texteditor Nano, um eine neue Datei namens conditional_example.yml zu erstellen. Fügen Sie nun den folgenden Inhalt hinzu:

---
- name: Conditional Example
  hosts: localhost
  gather_facts: yes
  tasks:
    - name: Check OS family
      debug:
        msg: "This is a Debian-based system"
      when: ansible_os_family == "Debian"

    - name: Check OS family (alternative)
      debug:
        msg: "This is not a Debian-based system"
      when: ansible_os_family != "Debian"

Schauen wir uns das im Detail an:

  • --- am Anfang der Datei kennzeichnet den Beginn eines YAML-Dokuments.
  • name: Conditional Example gibt unserem Playbook einen Namen.
  • hosts: localhost legt fest, dass dieses Playbook auf dem lokalen Computer ausgeführt wird.
  • gather_facts: yes weist Ansible an, vor dem Ausführen von Tasks Informationen über das System zu sammeln. Dies ist wichtig, da wir diese Fakten (Facts) in unseren Bedingungen verwenden werden.
  • tasks: beginnt die Liste der auszuführenden Tasks.

Jeder Task verwendet das debug-Modul, um eine Nachricht auszugeben, aber die Ausführung wird durch die when-Klausel gesteuert:

  • Der erste Task wird nur ausgeführt, wenn das System Debian-basiert ist (ansible_os_family == "Debian").
  • Der zweite Task wird nur ausgeführt, wenn das System nicht Debian-basiert ist (ansible_os_family != "Debian").

ansible_os_family ist ein von Ansible gesammeltes Faktum über das Zielsystem. Es wird hier verwendet, um zu demonstrieren, wie Bedingungen funktionieren.

Speichern Sie die Datei und verlassen Sie den Nano-Editor (Ctrl+X, dann Y, dann Enter).

Führen Sie nun das Playbook aus:

ansible-playbook -i ../inventory.ini conditional_example.yml

Dieser Befehl weist Ansible an, unser Playbook auszuführen. Die Option -i ../inventory.ini gibt die zuvor erstellte Inventardatei an.

Sie sollten eine Ausgabe sehen, die angibt, ob Ihr System Debian-basiert ist oder nicht. Je nach der Betriebssystemfamilie Ihres Systems wird nur eine der Debug-Meldungen angezeigt.

Dieses Beispiel zeigt, wie Bedingungen verwendet werden können, um Ihre Playbooks an verschiedene Umgebungen anzupassen. In realen Szenarien könnten Sie Bedingungen verwenden, um unterschiedliche Pakete auf verschiedenen Betriebssystemtypen zu installieren oder bestimmte Tasks zu überspringen, wenn eine Datei bereits existiert.

Denken Sie daran: Die Stärke von Bedingungen liegt darin, dass sie Ihre Playbooks flexibel machen und verschiedene Szenarien bewältigen können, ohne für jeden Fall separate Playbooks zu benötigen.

Arbeiten mit mehreren Bedingungen

In diesem Schritt kombinieren Sie mehrere Bedingungen mithilfe logischer Operatoren, bevor Sie einen Task ausführen. Dieses Muster unterstützt fortgeschrittenere bedingte Verhaltensweisen in praxisnahen Playbooks.

Erstellen Sie eine neue Datei namens multiple_conditions.yml:

nano multiple_conditions.yml

Fügen Sie nun den folgenden Inhalt in die Datei ein:

---
- name: Multiple Conditions Example
  hosts: localhost
  gather_facts: yes
  vars:
    check_memory: true
  tasks:
    - name: Check OS and Memory
      debug:
        msg: "This is a Debian-based system with more than 1GB of memory"
      when:
        - ansible_os_family == "Debian"
        - ansible_memtotal_mb > 1024
        - check_memory | bool

    - name: Print System Information
      debug:
        msg: "OS: {{ ansible_distribution }}, Memory: {{ ansible_memtotal_mb }} MB"
      when: ansible_distribution == "Ubuntu" or ansible_memtotal_mb < 2048

Schauen wir uns dieses Playbook an:

  • Wir definieren eine Variable check_memory auf Playbook-Ebene. Diese könnte dynamisch gesetzt oder beim Ausführen des Playbooks als zusätzliche Variable übergeben werden.

  • Der erste Task verwendet mehrere Bedingungen:

    • Er prüft, ob die Betriebssystemfamilie Debian ist.
    • Er prüft, ob der Gesamtspeicher größer als 1024 MB (1 GB) ist.
    • Er prüft, ob die Variable check_memory wahr (true) ist.

    Alle diese Bedingungen müssen erfüllt sein, damit der Task ausgeführt wird. Das | in check_memory | bool ist ein Filter, der den Wert in einen booleschen Wert konvertiert.

  • Der zweite Task demonstriert die Verwendung des or-Operators. Er wird ausgeführt, wenn entweder die Distribution Ubuntu ist ODER der Gesamtspeicher weniger als 2048 MB (2 GB) beträgt.

  • Wir verwenden hier weitere Ansible-Fakten: ansible_distribution liefert den spezifischen Distributionsnamen und ansible_memtotal_mb stellt den Gesamtspeichers des Systems in Megabyte bereit.

Speichern Sie die Datei und verlassen Sie den Nano-Editor.

Führen Sie dieses Playbook nun aus:

ansible-playbook -i ../inventory.ini multiple_conditions.yml

Beobachten Sie die Ausgabe. Abhängig von den Eigenschaften Ihres Systems sehen Sie möglicherweise eine oder beide Debug-Meldungen.

Dieses Beispiel zeigt, wie Sie komplexe Bedingungen erstellen können, um Ihre Playbooks hochgradig an verschiedene Szenarien anzupassen. Sie können verschiedene Systemfakten, benutzerdefinierte Variablen und logische Operatoren kombinieren, um genau zu steuern, wann Ihre Tasks ausgeführt werden sollen.

Einführung in Schleifen

In diesem Schritt verwenden Sie Ansible-Schleifen, um einen Task mit unterschiedlichen Werten zu wiederholen. Dies ist nützlich, wenn Sie dieselbe Aktion mit mehreren Elementen ausführen müssen, z. B. das Erstellen mehrerer Benutzer, das Installieren mehrerer Pakete oder das Anlegen mehrerer Verzeichnisse.

Erstellen wir ein Playbook, das die Verwendung von Schleifen demonstriert. Erstellen Sie eine neue Datei namens loop_example.yml:

nano loop_example.yml

Fügen Sie nun den folgenden Inhalt hinzu:

---
- name: Loop Example
  hosts: localhost
  vars:
    fruits:
      - apple
      - banana
      - cherry
  tasks:
    - name: Print fruit names
      debug:
        msg: "Current fruit: {{ item }}"
      loop: "{{ fruits }}"

    - name: Create directories
      file:
        path: "/tmp/{{ item }}"
        state: directory
      loop:
        - dir1
        - dir2
        - dir3

Schauen wir uns das genauer an:

  • Wir definieren eine Variable fruits als Liste von Fruchtname.

  • Der erste Task verwendet eine Schleife, um über die Liste fruits zu iterieren. Bei jeder Iteration ist der aktuelle Wert als {{ item }} verfügbar.

  • Der zweite Task zeigt, wie man eine Schleife mit dem file-Modul verwendet, um mehrere Verzeichnisse zu erstellen. Wir erstellen drei Verzeichnisse im /tmp-Ordner.

  • Beachten Sie, dass wir die Schleife direkt im Task verwenden können (wie im zweiten Task) oder auf eine Variable verweisen können (wie im ersten Task).

Speichern Sie die Datei und verlassen Sie den Nano-Editor.

Führen Sie dieses Playbook nun aus:

ansible-playbook -i ../inventory.ini loop_example.yml

Wenn Sie dieses Playbook ausführen, werden Sie sehen, dass der erste Task jeden Fruchtname ausgibt und der zweite Task drei Verzeichnisse in /tmp erstellt.

Schleifen sind eine leistungsstarke Funktion in Ansible, die den Umfang an repetitivem Code in Ihren Playbooks erheblich reduzieren kann. Sie sind besonders nützlich, wenn Sie mit Listen von Elementen wie Benutzern, Paketen oder Dateien arbeiten.

Fortgeschrittene Schleifentechniken

In diesem Schritt verwenden Sie fortgeschrittene Ansible-Schleifentechniken, um mit komplexen Datenstrukturen zu arbeiten und den Schleifenprozess zu steuern.

Erstellen Sie eine neue Datei namens advanced_loops.yml:

nano advanced_loops.yml

Fügen Sie nun den folgenden Inhalt hinzu:

---
- name: Advanced Loop Techniques
  hosts: localhost
  vars:
    users:
      - name: alice
        groups: ["developers", "testers"]
      - name: bob
        groups: ["managers", "developers"]
  tasks:
    - name: Create users with groups
      debug:
        msg: "Creating user {{ item.name }} with groups: {{ item.groups | join(', ') }}"
      loop: "{{ users }}"

    - name: Demonstrate loop_control
      debug:
        msg: "Processing item {{ index }} - {{ item }}"
      loop: ["a", "b", "c", "d"]
      loop_control:
        index_var: index

    - name: Loop over dictionary
      debug:
        msg: "{{ key }}: {{ value }}"
      loop: "{{ {'x': 1, 'y': 2, 'z': 3} | dict2items }}"
      vars:
        key: "{{ item.key }}"
        value: "{{ item.value }}"

Schauen wir uns diese fortgeschrittenen Techniken an:

  • Schleifen über eine Liste von Wörterbüchern (Dictionaries): Der erste Task iteriert über die Liste users, wobei jedes Element ein Wörterbuch ist, das einen Namen und eine Liste von Gruppen enthält. Wir können über die Punktschreibweise auf diese verschachtelten Elemente zugreifen (item.name, item.groups).

  • Verwendung von loop_control: Der zweite Task demonstriert loop_control, womit wir den Namen der Schleifenvariable ändern können (Standard ist item) und auf den aktuellen Schleifenindex zugreifen können. Hier verwenden wir index_var: index, um eine Variable index zu erstellen, die die aktuelle Iterationsnummer nachhält.

  • Schleifen über ein Wörterbuch: Der letzte Task zeigt, wie man über ein Wörterbuch (Dictionary) iteriert. Wir verwenden den Filter dict2items, um das Wörterbuch in eine Liste von Schlüssel-Wert-Paaren zu konvertieren, über die iteriert werden kann. Anschließend verwenden wir item.key und item.value, um auf die Schlüssel und Werte des Wörterbuchs zuzugreifen.

Speichern Sie die Datei und verlassen Sie den Nano-Editor.

Führen Sie dieses Playbook nun aus:

ansible-playbook -i ../inventory.ini advanced_loops.yml

Wenn Sie dieses Playbook ausführen, sehen Sie, wie diese fortgeschrittenen Schleifentechniken funktionieren. Die Ausgabe zeigt:

  • Nachrichten zur Benutzserstellung mit den jeweiligen Gruppen
  • Elemente, die mit ihrem Index verarbeitet werden
  • Schlüssel-Wert-Paare aus dem Wörterbuch

Diese fortgeschrittenen Techniken ermöglichen es Ihnen, mit komplexeren Datenstrukturen zu arbeiten und eine feinere Kontrolle über Ihre Schleifen auszuüben. Sie sind besonders nützlich im Umgang mit verschachtelten Daten, wenn Sie den Schleifenindex nachhalten müssen oder mit Wörterbüchern arbeiten.

Zusammenfassung

In diesem Lab haben Sie Ansible-Bedingungen und -Schleifen kennengelernt – zwei leistungsstarke Funktionen, mit denen Sie dynamischere und effizientere Playbooks erstellen können. Hier sind die wichtigsten Erkenntnisse:

  1. Bedingungen (die when-Klausel) ermöglichen es Ihnen, die Task-Ausführung basierend auf spezifischen Bedingungen zu steuern, wie zum Beispiel Fakten über das Zielsystem oder benutzerdefinierten Variablen.
  2. Sie können mehrere Bedingungen mithilfe logischer Operatoren wie and und or kombinieren, um komplexere bedingte Anweisungen zu erstellen.
  3. Schleifen (das Schlüsselwort loop) ermöglichen es Ihnen, Tasks mit unterschiedlichen Werten zu wiederholen, was die Effizienz steigert und die Komplexität des Playbooks verringert.
  4. Ansible unterstützt verschiedene Schleifentypen, einschließlich Schleifen über Listen, Wörterbücher und komplexere Datenstrukturen.
  5. Fortgeschrittene Schleifentechniken wie loop_control und Schleifen über Wörterbücher bieten noch mehr Flexibilität bei der Handhabung repetitiver Aufgaben.

Diese Funktionen sind unerlässlich, um flexible und leistungsstarke Ansible-Playbooks zu erstellen, die sich an verschiedene Szenarien anpassen und mehrere Elemente effizient verwalten können. Üben Sie bei Ihrer weiteren Arbeit mit Ansible die Einbindung von Bedingungen und Schleifen in Ihre Playbooks, um diese dynamischer und effizienter zu gestalten.

Denken Sie bei der Verwendung dieser Funktionen immer an die Lesbarkeit und Wartbarkeit Ihrer Playbooks. Obwohl sie Ihren Code stark vereinfachen können, können eine Übernutzung oder allzu komplexe Bedingungen und Schleifen dazu führen, dass Playbooks schwer verständlich und schwer zu warten sind.