Beide Menüs aktualisieren

AnsibleBeginner
Jetzt üben

Einführung

Juniper & Oat benötigt in zwei Cafés dieselben freigegebenen Getränkepreise, ohne die jeweiligen Namen, Öffnungszeiten oder lokalen Spezialitäten zu verlieren. Du aktualisierst zwei echte, über SSH verwaltete Ziele mit einem Ansible-Template und Playbook und behebst anschließend eine absichtlich erzeugte Menüabweichung.

Du brauchst grundlegende Terminalnavigation und Erfahrung beim Lesen eines kleinen Ansible-Inventars und Playbooks. Hostvariablen, JSON-Rendering, sichere Vorschauen und die Unterschiede zwischen verwalteten und lokalen Inhalten werden bei ihrer Verwendung erklärt. Vorbereitete Werkzeuge und Webseiten lassen dich auf Automatisierung statt Installation konzentrieren.

Gemeinsame Preise von Filialdaten trennen

In diesem Schritt erkennst du, was beide Cafés gemeinsam haben und was unterschiedlich bleiben muss. Danach deklarierst du die freigegebenen Daten für ein wiederverwendbares Template.

Juniper & Oat hat zwei Nachbarschaftscafés. Beide nutzen dieselben Standardgetränke und Preise, haben aber eigene Öffnungszeiten, Spezialitäten und lokale Hinweise. Du aktualisierst das gemeinsame Menü, ohne diese Angaben zu ersetzen. Die vorbereiteten Hosts web1 und web2 sind zwei über SSH verwaltete Container mit demselben Kernel der Trainings-VM, keine unabhängigen VMs. Controller führt Ansible aus; auf jedem Ziel läuft ein eigener echter Menüservice.

Öffne Menu Preview, wähle First branch und lies Menü, Öffnungszeiten und Spezialität. Gehe mit der Zurück-Schaltfläche des Browsers zur Filialliste zurück und wähle Second branch. Beide zeigen einen alten Preis für Flat white; bei Park Café sind auch die Öffnungszeiten falsch. Lokale Spezialitäten und Hinweise stimmen bereits. Visit öffnet die Besuchsinformationen derselben Filiale; Download menu lädt deren aktuelle echte CSV herunter. Das sind Seitenlinks, keine LabEx-Tabs.

Wechsle zum Tab Controller. Das Terminal beginnt im Projektverzeichnis. Dieser ausdrückliche Befehl bringt dich auch nach einem Verzeichnisfehler dorthin zurück:

cd /home/labex/project

Die Inventarnamen web1 und web2 verweisen auf unterschiedliche vorbereitete SSH-Ziele. Lies das Inventar und die freigegebenen Filialeingaben mit cat; dabei werden Dateien angezeigt, nicht verändert:

cat inventory.ini
cat host_vars/web1.yml host_vars/web2.yml

Harbor Café soll 07:00–16:00 geöffnet sein, Park Café 08:00–18:00. Das Verzeichnis host_vars liefert Variablen für den gleichnamigen Inventarhost. Behalte diese Eingaben und die vorbereiteten SSH-Einstellungen bei. Ihre Unterschiede sind beabsichtigt und keine zu beseitigenden Fehler.

Das freigegebene gemeinsame Menü liegt als Szenariodaten vor. Lies es, bevor du Variablen schreibst:

cat approved-menu.json

Es enthält Espresso für 3.20, Flat white für 4.20 und Tea für 3.00. Ein Preis wird als Zeichenkette in Anführungszeichen gespeichert, damit beide Dezimalstellen beim Formatieren erhalten bleiben. menu_items wird eine von beiden Hosts genutzte YAML-Liste aus Name/Preis-Objekten.

Die vorbereiteten Verzeichnisse group_vars und templates sind leer. Die Datei group_vars/all.yml liefert Variablen an alle Inventarhosts. Das folgende Here-Dokument schreibt eine vollständige Datei: > ersetzt genau dieses Ziel, und der zitierte Begrenzer YAML verhindert die Expansion des Inhalts durch die Shell. Der abschließende Begrenzer muss allein am Zeilenanfang stehen. Bei einem Tippfehler führst du den ganzen Block erneut aus; er ersetzt nur deine Variablendatei.

cat > group_vars/all.yml <<'YAML'
menu_items:
  - name: Espresso
    price: "3.20"
  - name: Flat white
    price: "4.20"
  - name: Tea
    price: "3.00"
YAML

Ein Jinja-Template setzt aufgelöste Werte in eine verwaltete Datei ein. Doppelte geschweifte Klammern werten einen Ausdruck aus; der senkrechte Strich wendet einen Filter an. Hier serialisiert to_nice_json das gesamte Objekt als gültiges, lesbares JSON einschließlich Nicht-ASCII-Zeichen. Dadurch musst du Werte nicht einzeln manuell zitieren. Beide Filialen verwenden dasselbe Template: branch_name und opening_hours stammen aus den jeweiligen Hostdaten, menu_items ist gemeinsam.

cat > templates/menu.json.j2 <<'JINJA'
{{ {'branch': branch_name, 'hours': opening_hours, 'items': menu_items} | to_nice_json }}
JINJA

Lies beide verfassten Quelldateien vor dem Ansible-Aufruf, um fehlende Anführungszeichen, falsche Einrückungen oder Begrenzer zu entdecken:

cat group_vars/all.yml templates/menu.json.j2

Die Webseite hat sich noch nicht geändert. Du hast die gewünschten Daten deklariert, aber nicht angewendet. Im nächsten Schritt rendert Ansible diese Quelle im Variablenkontext des jeweiligen Hosts.

Ein Playbook auf beide Cafés anwenden

In diesem Schritt prüfst und verteilst du dieselbe Deklaration auf beide echten SSH-Ziele und verwendest anschließend deren tatsächliche Menüs und Downloads.

Bleibe in Controller unter /home/labex/project. Ein Play wählt Hosts aus, Tasks deklarieren verwalteten Zustand. become: true fordert die vorbereitete, erlaubte Rechteerweiterung auf dem Ziel an, damit Dateien root gehören können. Das ändert nicht das LabEx-Anmeldekonto. Das Modul file deklariert das Verzeichnis; template rendert die gemeinsame Quelle und ersetzt nur menu.json. Ausdrückliche Eigentümer und zitierte Berechtigungen machen Verzeichniszugriff und öffentliches Lesen vorhersehbar: 0755 für das Verzeichnis und 0644 für das Menü.

Die lokalen Dateien local-special.txt, local-notice.txt und die private staff-notes.txt liegen außerhalb deiner Menüdeklaration. Ersetze den Verzeichnisinhalt nicht und ändere diese Dateien nicht. Erhalte ihre Bytes, root-Eigentümer und ursprünglichen Berechtigungen: 0644 für Spezialität/Hinweis und 0600 für private Notizen. Der Dienst liest menu.json bei jeder Anfrage. Ein reines Datenupdate braucht daher keinen künstlichen Neustart oder Handler.

Schreibe ein vollständiges Playbook. YAML-Listenelemente verwenden -; Leerzeichen verschachteln die Modulargumente. Pfade unter src bezeichnen Controllerquellen, dest liegt auf dem jeweiligen verwalteten Ziel.

cat > menus.yml <<'YAML'
- name: Keep both branch menus current
  hosts: all
  gather_facts: false
  become: true
  tasks:
    - name: Keep the menu directory available
      ansible.builtin.file:
        path: /srv/branch-menu
        state: directory
        owner: root
        group: root
        mode: "0755"

    - name: Render the shared menu with each branch's inputs
      ansible.builtin.template:
        src: templates/menu.json.j2
        dest: /srv/branch-menu/menu.json
        owner: root
        group: root
        mode: "0644"
YAML

Prüfe zuerst mit --syntax-check die Syntax, ohne das Playbook anzuwenden:

ansible-playbook menus.yml --syntax-check

Bei einem YAML-Fehler lies die angegebene Datei und Zeile. Vergleiche die Einrückung mit dem vollständigen Block oben, schreibe diesen Block erneut und wiederhole die Syntaxprüfung. Ansible-Syntaxfehler erfordern keinen VM-Reset.

--check sagt Änderungen unterstützter Module voraus, --diff zeigt den vorgeschlagenen Vorher-Nachher-Inhalt. Das ist für diese nicht geheimen Menüdateien nützlich; eine Vorschau ersetzt jedoch keinen echten Funktionstest. Verwende beide Optionen gemeinsam:

ansible-playbook menus.yml --check --diff

Beide Hosts sollten eine Menüänderung vorhersagen. Der Diff sollte Preise und Park Cafés Öffnungszeiten korrigieren, die Filialidentitäten aber getrennt halten. Zieldateien sind noch unverändert. Wechsle zu Menu Preview, öffne oder aktualisiere die Filialen und bestätige, dass die alten Werte sichtbar bleiben. Wechsle zurück zu Controller und wende dieselbe Deklaration ohne Vorschauoptionen an:

ansible-playbook menus.yml

Die Zusammenfassung jedes Hosts sollte weder unerreichbare Ziele noch fehlgeschlagene Tasks zeigen. Die genaue Zahl bei changed darf unterschiedlich sein, weil unterschiedliche Korrekturen nötig waren. Lies die echten Zieldaten mit einem Ad-hoc-Befehl: all wählt beide Inventarhosts, -m nennt das Modul und -a übergibt dessen Argumente. Das Modul command führt cat auf jedem Ziel aus, nicht auf dem Controller.

ansible all -m ansible.builtin.command -a 'cat /srv/branch-menu/menu.json'

Beide sollten die freigegebenen Standardgetränke und Preise enthalten. Harbor Café und Park Café müssen ihre unterschiedlichen Namen und Öffnungszeiten behalten.

Wechsle jetzt zu Menu Preview und aktualisiere jede Filiale. Lies die drei Preise, Namen, Öffnungszeiten, Spezialitäten und Hinweise. Öffne Visit und gehe über Menu zurück. Wähle Download menu und öffne die CSV: Sie muss die drei freigegebenen Artikel dieser Filiale und in jeder Zeile deren Namen enthalten. Eine funktionierende Startseite allein reicht nicht.

Harbor Café zeigt die freigegebenen gemeinsamen Preise neben eigenen Öffnungszeiten und der lokalen Spezialität.

Vergleiche die gemeinsamen Preise links mit der lokalen Spezialität rechts. Park Café behält eigene Öffnungszeiten und Spezialität bei derselben freigegebenen Getränkeliste.

Meldet der Browser fehlende oder ungültige Menüdaten, gehe zu Controller zurück, lies die Befehlsausgabe und vergleiche das JSON-Template mit Schritt 1. Korrigiere die Controllerquelle und wende das Playbook erneut an. Bei einem unerreichbaren Ziel lies inventory.ini und vergleiche es mit der ursprünglichen Ausgabe; deaktiviere keine SSH-Vertrauensprüfung und ändere keine Plattformkonten.

Kehre zu Controller zurück. Eine unveränderte Wiederholung sollte keine ausstehenden Änderungen haben:

ansible-playbook menus.yml

Achte auf beide Zusammenfassungszeilen:

web1 ... changed=0 ... unreachable=0 ... failed=0 ...
web2 ... changed=0 ... unreachable=0 ... failed=0 ...

Das ist idempotente Konfiguration: Die gewünschten Dateien stimmen bereits, deshalb schreibt Ansible sie nicht erneut. Normale Anfragen und Dienstprotokolle können trotzdem weiterhin entstehen.

Abweichungen beheben und lokale Inhalte erhalten

In diesem Schritt verfälschst du absichtlich einen verwalteten Menüwert und stellst ihn mit der unveränderten Controllerquelle wieder her. Lokale Inhalte bleiben erhalten.

Bleibe in Controller. Eine Konfigurationsabweichung liegt vor, wenn der echte verwaltete Zustand nicht mehr zur deklarierten Absicht passt. Unterschiedliche freigegebene Filialöffnungszeiten sind keine Abweichung. Ein manuell geänderter gemeinsamer Preis ist eine.

Der folgende Fehler ist beabsichtigt und auf web1 begrenzt. -b fordert become für diesen Ad-hoc-Task an. content des Moduls copy ersetzt genau die genannte Menü-JSON-Datei, nicht das Verzeichnis. Die Struktur bleibt richtig, aber der Espresso-Preis 0.01 ist nicht freigegeben. Diese vorübergehende Datei ist absichtlich falsch; übernimm den Preis nicht in group_vars.

ansible web1 -b -m ansible.builtin.copy -a 'dest=/srv/branch-menu/menu.json content={"branch":"Harbor Café","hours":"07:00–16:00","items":[{"name":"Espresso","price":"0.01"},{"name":"Flat white","price":"4.20"},{"name":"Tea","price":"3.00"}]} owner=root group=root mode=0644'

Wechsle zu Menu Preview, aktualisiere First branch und sieh dir den falschen Espresso-Preis an. Die zweite Filiale und beide lokalen Spezialitäten müssen unverändert bleiben. Das ist eine echte Zieldateiänderung, keine simulierte rote Statusanzeige.

Wechsle zurück zu Controller. Bearbeite die ursprünglichen Quellen nicht. Sieh dir den bestehenden Sollzustand an:

ansible-playbook menus.yml --check --diff

Nur web1 sollte eine Änderung vorhersagen. Web2 entspricht bereits seinem freigegebenen Zustand. Wende dasselbe Playbook an, um das verwaltete Menü wiederherzustellen:

ansible-playbook menus.yml

Gehe zu Menu Preview und aktualisiere beide Filialen. Espresso sollte wieder 3.20 kosten. Spezialitäten, Hinweise, Öffnungszeiten und Downloads müssen weiterhin stimmen. Die Automatisierung verwaltet eine Konfigurationsdatei, nicht sämtliche lokalen Dateien des Verzeichnisses.

Kehre zu Controller zurück und wiederhole ein letztes Mal:

ansible-playbook menus.yml

Beide Zusammenfassungen sollten wieder changed=0, unreachable=0 und failed=0 zeigen. Die erfolgreiche Reparatur beruht auf wiederverwendbarer Absicht in den Controllerdaten und einem gemeinsamen Template, nicht auf einer einmaligen manuellen Zielkorrektur. Dasselbe Template soll auch bei künftigen freigegebenen Änderungen gemeinsamer Artikel nutzbar bleiben.

Zusammenfassung

Du hast gemeinsame Preise, Filialeingaben und lokale Inhalte getrennt, ein Template für zwei SSH-Ziele vorab geprüft und angewendet, echte Seiten und CSV-Downloads genutzt und eine reale Konfigurationsabweichung behoben, ohne berechtigte Unterschiede zu löschen. Die unveränderte Wiederholung bestätigte, dass die deklarierten Menüs konvergiert waren.