diff --git a/README.md b/README.md index fd30e2d..08bdb19 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ lauffähigen Beispiel-Projekt. Alles in Python generiert und reproduzierbar. ``` ansible_präsentation/ -├── ansible_praesentation.pptx # Die fertige Präsentation (19 Folien, 16:9) +├── ansible_praesentation.pptx # Die fertige Präsentation (21 Folien, 16:9) ├── create_presentation.py # Python-Skript, das die .pptx erzeugt ├── handout.md # Handout (Markdown-Quelle) ├── handout.docx # Handout (druckbar/editierbar, für OnlyOffice) @@ -25,7 +25,7 @@ ansible_präsentation/ ## 1. Die Präsentation (`ansible_praesentation.pptx`) -19 Folien, 16:9, in den Ansible-Brandfarben (Rot `#EE0000`, Anthrazit `#1A1918`). +21 Folien, 16:9, in den Ansible-Brandfarben (Rot `#EE0000`, Anthrazit `#1A1918`). | # | Titel | Inhalt | |---|-------|--------| @@ -33,21 +33,23 @@ ansible_präsentation/ | 2 | Was ist Ansible? | Definition, Merkmale (agentenlos, idempotent, …) | | 3 | Architektur | Control Node, Managed Nodes (Diagramm) | | 4 | Vier Kernkonzepte | Playbooks, Inventory, Module, Rollen | -| 5 | YAML-Syntax | Grundregeln + Inventory-Beispiel | -| 6 | Playbook | site.yml mit Tasks & FQCN | -| 7 | Module | 6 Modul-Kategorien | -| 8 | Ad-hoc-Befehle | `ansible`-CLI ohne Playbook | -| 9 | Jinja2 | `{{ variable }}`, Filter, `.j2`-Templates | -| 10 | Gather Facts | Facts auslesen, Custom Facts, `gather_facts` | -| 11 | Variablen & Präzedenz | Quellen + Reihenfolge (wer gewinnt) | -| 12 | FQCN (Definition) | `namespace.collection.modul` | -| 13 | FQCN (Praxis) | Beispiele + Warum | -| 14 | Collections | Was sie sind (6 Bestandteile) | -| 15 | Collections nutzen | Galaxy, Installation, Struktur | -| 16 | Rollen (Konzept) | Wiederverwendbarkeit, Kapselung | -| 17 | Rollen (Struktur) | `roles/webserver/` Verzeichnisbaum | -| 18 | Praxisbeispiel | Playbook mit Rolle + Variablen | -| 19 | Zusammenfassung | Key-Takeaways + Quellen | +| 5 | ansible.cfg | Konfiguration, Suchreihenfolge (wer gewinnt) | +| 6 | ansible.cfg Parameter | Wichtige Werte in [defaults], [privilege_escalation], [ssh_connection] | +| 7 | YAML-Syntax | Grundregeln + Inventory-Beispiel | +| 8 | Playbook | site.yml mit Tasks & FQCN | +| 9 | Module | 6 Modul-Kategorien | +| 10 | Ad-hoc-Befehle | `ansible`-CLI ohne Playbook | +| 11 | Jinja2 | `{{ variable }}`, Filter, `.j2`-Templates | +| 12 | Gather Facts | Facts auslesen, Custom Facts, `gather_facts` | +| 13 | Variablen & Präzedenz | Quellen + Reihenfolge (wer gewinnt) | +| 14 | FQCN (Definition) | `namespace.collection.modul` | +| 15 | FQCN (Praxis) | Beispiele + Warum | +| 16 | Collections | Was sie sind (6 Bestandteile) | +| 17 | Collections nutzen | Galaxy, Installation, Struktur | +| 18 | Rollen (Konzept) | Wiederverwendbarkeit, Kapselung | +| 19 | Rollen (Struktur) | `roles/webserver/` Verzeichnisbaum | +| 20 | Praxisbeispiel | Playbook mit Rolle + Variablen | +| 21 | Zusammenfassung | Key-Takeaways + Quellen | **Design-Hinweis:** Die Präsentation nutzt die Schriftarten **Carlito** (Body) und **DejaVu Sans Mono** (Code), da Calibri/Consolas auf Linux oft fehlen und diff --git a/ansible_praesentation.pptx b/ansible_praesentation.pptx index d237610..353ad2d 100644 Binary files a/ansible_praesentation.pptx and b/ansible_praesentation.pptx differ diff --git a/create_presentation.py b/create_presentation.py index 4b8f7bd..b7b4864 100644 --- a/create_presentation.py +++ b/create_presentation.py @@ -168,16 +168,19 @@ def text(slide, x, y, w, h, runs, size=14, bold=False, color=BLACK, p.line_spacing = leading if space_after: p.space_after = Pt(space_after) - if isinstance(item, str): - item = {"t": item} - elif isinstance(item, tuple): - item = {"t": item[0], **item[1]} - r = p.add_run(); r.text = item["t"] - r.font.size = Pt(item.get("size", size)) - r.font.bold = item.get("bold", bold) - r.font.italic = item.get("italic", False) - r.font.name = item.get("font", font) - r.font.color.rgb = item.get("color", color) + # item: str | tuple | dict (ein Run) ODER list (mehrere Runs inline) + subs = item if isinstance(item, list) else [item] + for s in subs: + if isinstance(s, str): + s = {"t": s} + elif isinstance(s, tuple): + s = {"t": s[0], **s[1]} + r = p.add_run(); r.text = s["t"] + r.font.size = Pt(s.get("size", size)) + r.font.bold = s.get("bold", bold) + r.font.italic = s.get("italic", False) + r.font.name = s.get("font", font) + r.font.color.rgb = s.get("color", color) return box @@ -191,10 +194,14 @@ def header(slide, kicker, title, dark=False): slide.shapes.add_picture(logo, Inches(12.35), Inches(0.25), Inches(0.62), Inches(0.76)) -def footer(slide, num): +_page_no = 1 # Titel (Folie 1) zeigt keine sichtbare Nummer + +def footer(slide): + global _page_no + _page_no += 1 text(slide, 0.55, 7.08, 9.0, 0.3, "Ansible — moderne Automatisierung", size=8, color=MIDGRAY) - text(slide, 12.2, 7.08, 0.6, 0.3, str(num), size=9, color=MIDGRAY, align=PP_ALIGN.RIGHT) + text(slide, 12.2, 7.08, 0.6, 0.3, str(_page_no), size=9, color=MIDGRAY, align=PP_ALIGN.RIGHT) def _set_run(r, text, font_size, color, bold=False): @@ -304,7 +311,7 @@ rect(s, 9.0, 0, 4.333, 7.5, RED, rounded=False) if os.path.exists(LOGO_WHITE): s.shapes.add_picture(LOGO_WHITE, Inches(0.9), Inches(1.35), Inches(2.1), Inches(2.59)) text(s, 0.9, 4.15, 7.5, 0.4, "MODERNE IT-AUTOMATISIERUNG", size=14, bold=True, color=RED) -text(s, 0.9, 4.55, 8.0, 1.3, "Ansible", size=60, bold=True, color=WHITE) +text(s, 0.9, 4.55, 8.0, 0.95, "Ansible", size=60, bold=True, color=WHITE) text(s, 0.9, 5.75, 7.5, 0.4, "Agentenlos · Idempotent · Deklarativ · YAML", size=16, color=RGBColor(0xD8, 0xD8, 0xD8)) text(s, 0.9, 6.55, 7.5, 0.4, @@ -353,7 +360,7 @@ for big, small in facts: text(s, 9.15, yy, 1.8, 0.5, big, size=22, bold=True, color=BLACK) text(s, 10.95, yy + 0.08, 2.2, 0.5, small, size=11, color=GRAY, leading=1.0) yy += 0.62 -footer(s, 2) +footer(s) # =========================================================================== @@ -380,7 +387,7 @@ for t, d in comp: text(s, 8.95, yy, 3.9, 0.3, t, size=13, bold=True, color=BLACK) text(s, 8.95, yy + 0.28, 3.9, 0.9, d, size=10.5, color=GRAY, leading=1.05) yy += 1.22 -footer(s, 3) +footer(s) # =========================================================================== @@ -400,11 +407,98 @@ card(s, 0.55, 4.3, 6.0, 2.4, "3", "Module", card(s, 6.85, 4.3, 6.0, 2.4, "4", "Rollen & Collections", "Rollen bündeln Tasks/Templates/Variablen zu wiederverwendbaren Einheiten. " "Collections verteilen Module, Rollen & Plugins.") -footer(s, 4) +footer(s) # =========================================================================== -# FOLIE 5 — YAML-Syntax +# FOLIE 5 — ansible.cfg (Konfiguration) +# =========================================================================== +s = new_slide(WHITE) +header(s, "Konfiguration", "ansible.cfg — die Konfigurationsdatei") +text(s, 0.55, 1.55, 12.2, 0.7, + "ansible.cfg steuert das Verhalten von Ansible global. INI-Format mit " + "Sektionen wie [defaults], [privilege_escalation] und [ssh_connection].", + size=13, color=BLACK, leading=1.15) + +# links: Suchreihenfolge (erste gefundene Datei gewinnt) +text(s, 0.55, 2.4, 5.5, 0.3, "SUCHREIHENFOLGE — WER GEWINNT?", size=11, bold=True, color=RED) +order = [ + ("ANSIBLE_CONFIG", "Umgebungsvariable"), + ("./ansible.cfg", "Projektverzeichnis"), + ("~/.ansible.cfg", "Home-Verzeichnis"), + ("/etc/ansible/ansible.cfg", "systemweit"), +] +yy = 2.9 +for i, (p, d) in enumerate(order, 1): + rect(s, 0.55, yy, 0.4, 0.4, RED, rounded=True, radius=0.3) + text(s, 0.55, yy + 0.03, 0.4, 0.34, str(i), size=13, bold=True, + color=WHITE, align=PP_ALIGN.CENTER) + text(s, 1.15, yy + 0.04, 2.55, 0.32, p, size=11.5, bold=True, + color=DARKRED, font=FONT_MONO) + text(s, 3.85, yy + 0.06, 2.2, 0.5, d, size=10, color=GRAY, leading=1.0) + yy += 0.62 +text(s, 0.55, yy + 0.15, 5.5, 0.6, + [[("Erste gefundene Datei gewinnt — ", {"bold": True}), + ("kein Zusammenführen!", {"bold": True, "color": RED})]], + size=11.5, color=BLACK) + +# rechts: Beispiel mit den wichtigsten Werten +code_block(s, 6.4, 2.4, 6.4, [ + "# ansible.cfg (INI-Format)", + "[defaults]", + "inventory = ./inventory.yml", + "remote_user = admin", + "forks = 20", + "host_key_checking = False", + "gather_facts = True", + "roles_path = ./roles", + "", + "[privilege_escalation]", + "become = True", + "become_method = sudo", + "", + "[ssh_connection]", + "pipelining = True", +], font_size=10.5, title="Beispiel") +footer(s) + + +# =========================================================================== +# FOLIE 6 — ansible.cfg Parameter +# =========================================================================== +s = new_slide(WHITE) +header(s, "Konfiguration", "ansible.cfg — wichtige Parameter") + +text(s, 0.55, 1.6, 3.9, 0.35, "[defaults]", size=13, bold=True, color=RED, font=FONT_MONO) +kv_rows(s, 0.55, 2.15, 3.9, [ + ("inventory", "Pfad zur Inventory-Datei"), + ("remote_user", "Standard-SSH-Benutzer"), + ("forks", "parallele Prozesse"), + ("host_key_checking", "SSH-Key-Prüfung"), + ("gather_facts", "Facts sammeln"), + ("roles_path", "Suchpfad für Rollen"), +], key_w=1.65, name_size=10.5, desc_size=10, gap=0.46) + +text(s, 4.7, 1.6, 3.9, 0.35, "[privilege_escalation]", size=13, bold=True, color=RED, font=FONT_MONO) +kv_rows(s, 4.7, 2.15, 3.9, [ + ("become", "sudo aktivieren"), + ("become_method", "sudo / su"), + ("become_user", "Ziel-Benutzer (root)"), + ("become_ask_pass", "Passwort abfragen"), +], key_w=1.7, name_size=10.5, desc_size=10, gap=0.46) + +text(s, 8.85, 1.6, 3.9, 0.35, "[ssh_connection]", size=13, bold=True, color=RED, font=FONT_MONO) +kv_rows(s, 8.85, 2.15, 3.9, [ + ("pipelining", "weniger SSH-Roundtrips"), + ("ssh_args", "zusätzl. SSH-Argumente"), + ("control_path", "ControlMaster-Socket"), +], key_w=1.5, name_size=10.5, desc_size=10, gap=0.46) + +footer(s) + + +# =========================================================================== +# FOLIE 7 — YAML-Syntax # =========================================================================== s = new_slide(WHITE) header(s, "Syntax", "YAML — die Sprache von Ansible") @@ -439,25 +533,25 @@ code_block(s, 6.5, 1.6, 6.3, [ " - git", " - curl", ], font_size=11) -footer(s, 5) +footer(s) # =========================================================================== -# FOLIE 6 — Playbook & Tasks +# FOLIE 8 — Playbook & Tasks # =========================================================================== s = new_slide(WHITE) header(s, "Syntax", "Ein Playbook in der Praxis") text(s, 0.55, 1.55, 5.6, 1.4, - [("Ein Playbook ", {}), - ("definiert, was passieren soll. ", {}), - ("plays", {"bold": True, "color": RED}), - (" wirken auf ", {}), - ("hosts", {"bold": True, "color": RED}), - (", jede ", {}), - ("task", {"bold": True, "color": RED}), - (" ruft genau ein ", {}), - ("Modul", {"bold": True, "color": RED}), - (" auf.", {})], + [[("Ein Playbook ", {}), + ("definiert, was passieren soll. ", {}), + ("plays", {"bold": True, "color": RED}), + (" wirken auf ", {}), + ("hosts", {"bold": True, "color": RED}), + (", jede ", {}), + ("task", {"bold": True, "color": RED}), + (" ruft genau ein ", {}), + ("Modul", {"bold": True, "color": RED}), + (" auf.", {})]], size=12.5, color=BLACK, leading=1.2) code_block(s, 6.5, 1.55, 6.3, [ "---", @@ -477,11 +571,11 @@ code_block(s, 6.5, 1.55, 6.3, [ " state: started", " enabled: true", ], font_size=10.5, title="site.yml") -footer(s, 6) +footer(s) # =========================================================================== -# FOLIE 7 — Module +# FOLIE 9 — Module # =========================================================================== s = new_slide(LIGHT) header(s, "Syntax", "Module — die Arbeitspferde") @@ -502,25 +596,25 @@ for i, (t, d) in enumerate(mods): col = i % 3; row = i // 3 card(s, 0.55 + col * 4.2, 2.6 + row * 1.75, 3.95, 1.5, "•", t, d) text(s, 0.55, 6.15, 12.2, 0.6, - [("Wichtig: Module werden heute über den ", {}), - ("FQCN", {"bold": True, "color": RED}), - (" referenziert (z.B. ", {}), - ("ansible.builtin.apt", {"font": FONT_MONO, "color": DARKRED}), - (").", {})], + [[("Wichtig: Module werden heute über den ", {}), + ("FQCN", {"bold": True, "color": RED}), + (" referenziert (z.B. ", {}), + ("ansible.builtin.apt", {"font": FONT_MONO, "color": DARKRED}), + (").", {})]], size=12, color=BLACK) -footer(s, 7) +footer(s) # =========================================================================== -# FOLIE 8 — Ad-hoc-Befehle +# FOLIE 10 — Ad-hoc-Befehle # =========================================================================== s = new_slide(WHITE) header(s, "Syntax", "Ad-hoc-Befehle — Ansible ohne Playbook") text(s, 0.55, 1.55, 5.7, 1.25, - [("Mit dem ", {}), - ("ansible", {"font": FONT_MONO, "color": DARKRED, "bold": True}), - ("-CLI lassen sich einzelne Module direkt ausführen — ohne Playbook. Ideal " - "für schnelle Checks und einmalige Aktionen.", {})], + [[("Mit dem ", {}), + ("ansible", {"font": FONT_MONO, "color": DARKRED, "bold": True}), + ("-CLI lassen sich einzelne Module direkt ausführen — ohne Playbook. Ideal " + "für schnelle Checks und einmalige Aktionen.", {})]], size=12.5, color=BLACK, leading=1.2) text(s, 0.55, 2.85, 5.7, 0.3, "AUFBAU", size=11, bold=True, color=RED) code_block(s, 0.55, 3.2, 5.7, [ @@ -552,11 +646,11 @@ code_block(s, 6.6, 1.55, 6.2, [ "ansible webserver -m service", " -a \"name=nginx state=restarted\"", ], font_size=10, title="Beispiele") -footer(s, 8) +footer(s) # =========================================================================== -# FOLIE 9 — Jinja2 (Templating) +# FOLIE 11 — Jinja2 (Templating) # =========================================================================== s = new_slide(WHITE) header(s, "Syntax", "Jinja2 — dynamische Inhalte") @@ -565,21 +659,21 @@ text(s, 0.55, 1.55, 12.2, 0.7, "und Dateien dynamisch erzeugt — in Playbooks, aber vor allem in Templates (.j2).", size=13, color=BLACK, leading=1.15) card(s, 0.55, 2.4, 4.0, 1.7, "1", "Variable auflösen", - [("{{ variable }}", {"font": FONT_MONO, "color": DARKRED, "bold": True}), - (" setzt den Wert einer Variablen an die Stelle im Text ein.", {})]) + [[("{{ variable }}", {"font": FONT_MONO, "color": DARKRED, "bold": True}), + (" setzt den Wert einer Variablen an die Stelle im Text ein.", {})]]) card(s, 4.75, 2.4, 4.0, 1.7, "2", "Filter anwenden", - [("{{ wert | filter }}", {"font": FONT_MONO, "color": DARKRED, "bold": True}), - (" transformiert Werte (z.B. ", {}), - ("upper", {"font": FONT_MONO}), - (", ", {}), - ("default", {"font": FONT_MONO}), - (").", {})]) + [[("{{ wert | filter }}", {"font": FONT_MONO, "color": DARKRED, "bold": True}), + (" transformiert Werte (z.B. ", {}), + ("upper", {"font": FONT_MONO}), + (", ", {}), + ("default", {"font": FONT_MONO}), + (").", {})]]) card(s, 8.95, 2.4, 3.85, 1.7, "3", "Template-Dateien", - [("Dateien mit Endung ", {}), - (".j2", {"font": FONT_MONO, "color": DARKRED, "bold": True}), - (" werden vom Modul ", {}), - ("template", {"font": FONT_MONO}), - (" gerendert.", {})]) + [[("Dateien mit Endung ", {}), + (".j2", {"font": FONT_MONO, "color": DARKRED, "bold": True}), + (" werden vom Modul ", {}), + ("template", {"font": FONT_MONO}), + (" gerendert.", {})]]) code_block(s, 0.55, 4.35, 6.0, [ "# Variablen auflösen", "msg: \"Hallo {{ benutzer }}\"", @@ -596,22 +690,22 @@ code_block(s, 6.85, 4.35, 6.0, [ " root {{ web_root }};", "}", ], font_size=10.5, title="nginx.conf.j2") -footer(s, 9) +footer(s) # =========================================================================== -# FOLIE 10 — Gather Facts +# FOLIE 12 — Gather Facts # =========================================================================== s = new_slide(WHITE) header(s, "Facts", "Gather Facts — Systeminformationen") text(s, 0.55, 1.5, 12.2, 0.7, - [("Ansible sammelt beim Start automatisch ", {}), - ("Facts", {"bold": True}), - (" (Systeminfos) über jeden Host — über das Modul ", {}), - ("setup", {"font": FONT_MONO, "color": DARKRED}), - (", standardmäßig ", {}), - ("gather_facts: true", {"font": FONT_MONO, "color": DARKRED}), - (".", {})], + [[("Ansible sammelt beim Start automatisch ", {}), + ("Facts", {"bold": True}), + (" (Systeminfos) über jeden Host — über das Modul ", {}), + ("setup", {"font": FONT_MONO, "color": DARKRED}), + (", standardmäßig ", {}), + ("gather_facts: true", {"font": FONT_MONO, "color": DARKRED}), + (".", {})]], size=13, color=BLACK, leading=1.15) # Links: Facts als einzelne Spalte (breite Schlüssel-Spalte -> kein Umbruch) @@ -639,11 +733,11 @@ code_block(s, 7.55, 2.4, 5.2, [ "# Datei: /etc/ansible/facts.d/app.fact", "# Abruf: {{ ansible_local.app.version }}", ], font_size=11, title="Zugriff & Custom Facts") -footer(s, 10) +footer(s) # =========================================================================== -# FOLIE 11 — Variablen & Auflösung (Präzedenz) +# FOLIE 13 — Variablen & Auflösung (Präzedenz) # =========================================================================== s = new_slide(LIGHT) header(s, "Variablen", "Variablen definieren & auflösen") @@ -682,21 +776,21 @@ for i, (t, d) in enumerate(prec, 1): text(s, 11.0, yy + 0.02, 1.85, 0.34, d, size=9, color=GRAY, font=FONT_MONO) yy += 0.5 text(s, 6.85, yy + 0.1, 6.0, 0.6, - [("Faustregel: ", {"bold": True, "color": RED}), - ("je spezifischer die Quelle, desto höher die Priorität.", {})], + [[("Faustregel: ", {"bold": True, "color": RED}), + ("je spezifischer die Quelle, desto höher die Priorität.", {})]], size=11, color=GRAY) -footer(s, 11) +footer(s) # =========================================================================== -# FOLIE 12 — FQCN (Definition) +# FOLIE 14 — FQCN (Definition) # =========================================================================== s = new_slide(WHITE) header(s, "FQCN", "FQCN — Fully Qualified Collection Name") rect(s, 0.55, 1.55, 12.2, 0.95, LIGHT, line=BORDER, line_w=1.0, rounded=True, radius=0.1) text(s, 0.85, 1.77, 11.6, 0.55, - [("FQCN = ", {"bold": True, "color": RED}), - ("eindeutige, vollständige Referenz auf ein Modul oder Plugin.", {})], + [[("FQCN = ", {"bold": True, "color": RED}), + ("eindeutige, vollständige Referenz auf ein Modul oder Plugin.", {})]], size=16, color=BLACK) text(s, 0.85, 2.75, 11.6, 0.6, "namespace · collection · modul", size=28, bold=True, color=BLACK) @@ -710,16 +804,16 @@ code_block(s, 0.55, 3.6, 12.2, [ "# copy -> modul (die Funktion)", ], font_size=12, title="Beispiel") text(s, 0.55, 6.15, 12.2, 0.5, - [("NICHT verwechseln mit ", {"bold": True}), - ("FQDN", {"font": FONT_MONO, "color": DARKRED, "bold": True}), - (" (Fully Qualified Domain Name = Hostname)! Der FQCN macht eindeutig, " - "aus welcher Collection ein Modul stammt.", {})], + [[("NICHT verwechseln mit ", {"bold": True}), + ("FQDN", {"font": FONT_MONO, "color": DARKRED, "bold": True}), + (" (Fully Qualified Domain Name = Hostname)! Der FQCN macht eindeutig, " + "aus welcher Collection ein Modul stammt.", {})]], size=12.5, color=BLACK) -footer(s, 12) +footer(s) # =========================================================================== -# FOLIE 13 — FQCN (Beispiele & Warum) +# FOLIE 15 — FQCN (Beispiele & Warum) # =========================================================================== s = new_slide(WHITE) header(s, "FQCN", "FQCN in der Praxis") @@ -742,23 +836,23 @@ for fqcn, d in ex: text(s, 7.35, 1.6, 5.4, 0.4, "WARUM FQCN?", size=11, bold=True, color=RED) rect(s, 7.35, 2.1, 5.45, 4.35, LIGHT, line=BORDER, line_w=1.0, rounded=True, radius=0.05) text(s, 7.65, 2.35, 4.9, 3.9, [ - ("Seit Ansible 2.10 sind Module in ", {}), - ("Collections", {"bold": True}), - (" gebündelt.\n\n", {}), - ("Der FQCN macht eindeutig, ", {}), - ("welches Modul", {"bold": True}), - (" gemeint ist.\n\n", {}), - ("Er vermeidet ", {}), - ("Namenskollisionen", {"bold": True}), - (" — mehrere Collections können ein gleichnamiges Modul anbieten.\n\n", {}), - ("Faustregel: ", {"bold": True, "color": RED}), - ("immer den FQCN verwenden, nie die Kurzform.", {}), -], size=12.5, color=BLACK, leading=1.25) -footer(s, 13) + [("Seit Ansible 2.10 sind Module in ", {}), + ("Collections", {"bold": True}), + (" gebündelt.", {})], + [("Der FQCN macht eindeutig, ", {}), + ("welches Modul", {"bold": True}), + (" gemeint ist.", {})], + [("Er vermeidet ", {}), + ("Namenskollisionen", {"bold": True}), + (" — mehrere Collections können ein gleichnamiges Modul anbieten.", {})], + [("Faustregel: ", {"bold": True, "color": RED}), + ("immer den FQCN verwenden, nie die Kurzform.", {})], +], size=12.5, color=BLACK, leading=1.25, space_after=8) +footer(s) # =========================================================================== -# FOLIE 14 — Collections (Definition) +# FOLIE 16 — Collections (Definition) # =========================================================================== s = new_slide(LIGHT) header(s, "Collections", "Was sind Collections?") @@ -778,19 +872,19 @@ cols = [ for i, (t, d) in enumerate(cols): col = i % 3; row = i // 3 card(s, 0.55 + col * 4.2, 3.0 + row * 1.6, 3.95, 1.35, "•", t, d) -footer(s, 14) +footer(s) # =========================================================================== -# FOLIE 15 — Collections (Struktur & Galaxy) +# FOLIE 17 — Collections (Struktur & Galaxy) # =========================================================================== s = new_slide(WHITE) header(s, "Collections", "Collections nutzen") text(s, 0.55, 1.55, 5.8, 0.3, "BEZUGSQUELLE", size=11, bold=True, color=RED) text(s, 0.55, 1.9, 5.8, 0.85, - [("Ansible Galaxy", {"bold": True}), - (" (galaxy.ansible.com) ist der zentrale Hub — vergleichbar mit einem " - "Paket-Manager für Ansible-Inhalte.", {})], + [[("Ansible Galaxy", {"bold": True}), + (" (galaxy.ansible.com) ist der zentrale Hub — vergleichbar mit einem " + "Paket-Manager für Ansible-Inhalte.", {})]], size=12, color=BLACK, leading=1.15) text(s, 0.55, 2.85, 5.8, 0.3, "INSTALLATION", size=11, bold=True, color=RED) code_block(s, 0.55, 3.25, 5.8, [ @@ -805,11 +899,11 @@ code_block(s, 0.55, 3.25, 5.8, [ ], font_size=11, title="galaxy") text(s, 6.85, 1.55, 5.9, 0.3, "NAMENSSCHEMA", size=11, bold=True, color=RED) text(s, 6.85, 1.9, 5.9, 0.45, - [("namespace", {"font": FONT_MONO, "color": DARKRED, "bold": True}), - (" . ", {"color": BLACK, "bold": True}), - ("name", {"font": FONT_MONO, "color": DARKRED, "bold": True}), - (" → z.B. ", {}), - ("ansible.posix", {"font": FONT_MONO, "color": DARKRED, "bold": True})], + [[("namespace", {"font": FONT_MONO, "color": DARKRED, "bold": True}), + (" . ", {"color": BLACK, "bold": True}), + ("name", {"font": FONT_MONO, "color": DARKRED, "bold": True}), + (" → z.B. ", {}), + ("ansible.posix", {"font": FONT_MONO, "color": DARKRED, "bold": True})]], size=14) text(s, 6.85, 2.5, 5.9, 0.3, "AUFBAU EINER COLLECTION", size=11, bold=True, color=RED) code_block(s, 6.85, 2.9, 5.9, [ @@ -821,11 +915,11 @@ code_block(s, 6.85, 2.9, 5.9, [ " docs/", " galaxy.yml", ], font_size=11.5, title="ansible.posix") -footer(s, 15) +footer(s) # =========================================================================== -# FOLIE 16 — Rollen (Konzept) +# FOLIE 18 — Rollen (Konzept) # =========================================================================== s = new_slide(LIGHT) header(s, "Rollen", "Wie funktionieren Rollen?") @@ -844,16 +938,16 @@ points = [ for i, (t, d) in enumerate(points): col = i % 2; row = i // 2 card(s, 0.55 + col * 6.2, 3.0 + row * 1.8, 5.95, 1.55, "✓", t, d) -footer(s, 16) +footer(s) # =========================================================================== -# FOLIE 17 — Rollen (Verzeichnisstruktur) +# FOLIE 19 — Rollen (Verzeichnisstruktur) # =========================================================================== s = new_slide(WHITE) header(s, "Rollen", "Die Verzeichnisstruktur einer Rolle") text(s, 0.55, 1.55, 5.5, 0.3, "ANATOMIE", size=11, bold=True, color=RED) -text(s, 0.55, 1.9, 5.5, 0.9, +text(s, 0.55, 1.9, 5.5, 0.6, "Eine Rolle folgt einem festen Aufbau. Jede Datei hat eine klar definierte " "Aufgabe — Ansible lädt sie automatisch.", size=12, color=BLACK, leading=1.15) @@ -886,25 +980,25 @@ code_block(s, 6.7, 1.55, 6.1, [ " meta/", " main.yml", ], font_size=11.5, title="roles/webserver/") -footer(s, 17) +footer(s) # =========================================================================== -# FOLIE 18 — Praxisbeispiel +# FOLIE 20 — Praxisbeispiel # =========================================================================== s = new_slide(LIGHT) header(s, "Praxis", "Alles zusammen: Playbook mit Rolle") text(s, 0.55, 1.55, 5.3, 0.3, "ZUSAMMENSPIEL", size=11, bold=True, color=RED) -text(s, 0.55, 1.9, 5.3, 2.8, - [("Das Playbook referenziert die Rolle ", {}), - ("webserver", {"font": FONT_MONO, "color": DARKRED, "bold": True}), - (". FQCN-Module (", {}), - ("ansible.builtin.*", {"font": FONT_MONO, "color": DARKRED}), - (") arbeiten im Hintergrund.\n\n", {}), - ("1.", {"bold": True, "color": RED}), (" Rolle wird geladen.\n", {}), - ("2.", {"bold": True, "color": RED}), (" Aufgaben & Variablen aus der Rolle gelten.\n", {}), - ("3.", {"bold": True, "color": RED}), (" Idempotenz verhindert doppelte Arbeit.", {})], - size=12, color=BLACK, leading=1.25) +text(s, 0.55, 1.9, 5.3, 2.8, [ + [("Das Playbook referenziert die Rolle ", {}), + ("webserver", {"font": FONT_MONO, "color": DARKRED, "bold": True}), + (". FQCN-Module (", {}), + ("ansible.builtin.*", {"font": FONT_MONO, "color": DARKRED}), + (") arbeiten im Hintergrund.", {})], + [("1.", {"bold": True, "color": RED}), (" Rolle wird geladen.", {})], + [("2.", {"bold": True, "color": RED}), (" Aufgaben & Variablen aus der Rolle gelten.", {})], + [("3.", {"bold": True, "color": RED}), (" Idempotenz verhindert doppelte Arbeit.", {})], +], size=12, color=BLACK, leading=1.25, space_after=6) code_block(s, 6.15, 1.55, 6.6, [ "---", "- name: Webserver ausrollen", @@ -917,11 +1011,11 @@ code_block(s, 6.15, 1.55, 6.6, [ " vars:", " nginx_port: 8080", ], font_size=11, title="deploy.yml") -footer(s, 18) +footer(s) # =========================================================================== -# FOLIE 19 — Zusammenfassung & Quellen +# FOLIE 21 — Zusammenfassung & Quellen # =========================================================================== s = new_slide(LIGHT) header(s, "Fazit", "Zusammenfassung") @@ -949,7 +1043,7 @@ text(s, 10.05, 3.95, 2.5, 1.9, ["docs.ansible.com", "galaxy.ansible.com", "github.com/ansible", "Logo: Wikimedia Commons"], size=9.5, color=GRAY, leading=1.4) -footer(s, 19) +footer(s) # --------------------------------------------------------------------------- diff --git a/handout.docx b/handout.docx index 8441ee4..2c32f80 100644 Binary files a/handout.docx and b/handout.docx differ diff --git a/handout.md b/handout.md index ee4dae7..75af84b 100644 --- a/handout.md +++ b/handout.md @@ -1,6 +1,6 @@ # Ansible — Syntax & Variablen-Handout -Kompakte Referenz zu YAML-Syntax, Ad-hoc-Befehlen, Jinja2, Facts, Variablen-Auflösung und FQCN. +Kompakte Referenz zu YAML-Syntax, Ad-hoc-Befehlen, Jinja2, Facts, Variablen-Auflösung, FQCN und ansible.cfg. --- @@ -195,7 +195,54 @@ ansible.builtin.apt: --- -## 8. Vollständiges Beispiel +## 8. ansible.cfg — Konfiguration + +INI-Datei, die Ansible global steuert. Ansible nutzt die **erste** gefundene +Datei (kein Zusammenführen): + +1. `ANSIBLE_CONFIG` — Umgebungsvariable (expliziter Pfad) +2. `./ansible.cfg` — aktuelles Verzeichnis (Projekt) +3. `~/.ansible.cfg` — Home-Verzeichnis (Benutzer) +4. `/etc/ansible/ansible.cfg` — systemweit (Fallback) + +Wichtige Werte: + +| Sektion | Schlüssel | Bedeutung | +|---------------------------|--------------------|------------------------------------| +| `[defaults]` | `inventory` | Pfad zur Inventory-Datei | +| | `remote_user` | Standard-SSH-Benutzer | +| | `forks` | parallele Prozesse (Default 5) | +| | `host_key_checking`| SSH-Key-Prüfung (True/False) | +| | `gather_facts` | Facts automatisch sammeln | +| | `roles_path` | Suchpfad für Rollen | +| `[privilege_escalation]` | `become` | sudo aktivieren | +| | `become_method` | sudo / su | +| | `become_user` | Ziel-Benutzer (Default root) | +| `[ssh_connection]` | `pipelining` | Performance-Optimierung | +| | `ssh_args` | zusätzliche SSH-Argumente | + +Beispiel: + +```ini +[defaults] +inventory = ./inventory.yml +remote_user = admin +forks = 20 +host_key_checking = False +gather_facts = True +roles_path = ./roles + +[privilege_escalation] +become = True +become_method = sudo + +[ssh_connection] +pipelining = True +``` + +--- + +## 9. Vollständiges Beispiel **Playbook** (`deploy.yml`):