Anpassung für vault hinzugefügt
This commit is contained in:
+134
-32
@@ -2,7 +2,7 @@
|
||||
"""
|
||||
Moderne Ansible-Präsentation — vollständiger Generator (v3).
|
||||
|
||||
19 Folien (16:9) mit den Ansible-Brandfarben (Rot #EE0000, Anthrazit #1A1918).
|
||||
23 Folien (16:9) mit den Ansible-Brandfarben (Rot #EE0000, Anthrazit #1A1918).
|
||||
Fonts: Carlito (Body) + DejaVu Sans Mono (Code) — auf dem Zielsystem installiert
|
||||
und von OnlyOffice korrekt gerendert (kein Font-Substitution-Bruch).
|
||||
|
||||
@@ -11,6 +11,7 @@ Behandelt:
|
||||
- YAML-Syntax, Playbooks, Module, Ad-hoc-Befehle
|
||||
- Jinja2 (Templating) und Gather Facts
|
||||
- Variablen-Auflösung (Präzedenz)
|
||||
- Ansible Vault (verschlüsselte Variablen & Dateien)
|
||||
- FQCN (Fully Qualified Collection Name)
|
||||
- Collections
|
||||
- Rollen (Roles)
|
||||
@@ -38,8 +39,10 @@ from pptx.dml.color import RGBColor
|
||||
# Pfade & Farben
|
||||
# ---------------------------------------------------------------------------
|
||||
BASE = os.path.dirname(os.path.abspath(__file__))
|
||||
DOCS = os.path.join(BASE, "Dokumentation")
|
||||
ASSETS = os.path.join(BASE, "assets")
|
||||
os.makedirs(ASSETS, exist_ok=True)
|
||||
os.makedirs(DOCS, exist_ok=True)
|
||||
|
||||
LOGO_RED = os.path.join(ASSETS, "ansible_mark_red.png")
|
||||
LOGO_WHITE = os.path.join(ASSETS, "ansible_mark_white.png")
|
||||
@@ -49,7 +52,8 @@ BLACK = RGBColor(0x1A, 0x19, 0x18)
|
||||
RED = RGBColor(0xEE, 0x00, 0x00)
|
||||
DARKRED = RGBColor(0xB0, 0x00, 0x00)
|
||||
WHITE = RGBColor(0xFF, 0xFF, 0xFF)
|
||||
LIGHT = RGBColor(0xF7, 0xF7, 0xF7)
|
||||
LIGHT = RGBColor(0xF8, 0xF5, 0xF5) # warmgetöntes Off-White (Rot-Stich)
|
||||
REDTINT = RGBColor(0xFB, 0xE9, 0xE9) # dezente Rot-Tinktur für Akzentboxen
|
||||
CARD = RGBColor(0xFF, 0xFF, 0xFF)
|
||||
GRAY = RGBColor(0x55, 0x55, 0x55) # dunkler für bessere Lesbarkeit
|
||||
MIDGRAY = RGBColor(0x8A, 0x8A, 0x8A)
|
||||
@@ -150,6 +154,22 @@ def rect(slide, x, y, w, h, fill, line=None, line_w=1.0, rounded=False, radius=0
|
||||
return shp
|
||||
|
||||
|
||||
def grad_rect(slide, x, y, w, h, c1, c2, angle=0.0, rounded=False, radius=0.08):
|
||||
"""Rechteck mit linearem Farbverlauf (modern, in Markenfarben)."""
|
||||
shp = rect(slide, x, y, w, h, None, rounded=rounded, radius=radius)
|
||||
f = shp.fill
|
||||
f.gradient()
|
||||
stops = f.gradient_stops
|
||||
stops[0].color.rgb = c1
|
||||
stops[1].color.rgb = c2
|
||||
try:
|
||||
f.gradient_angle = angle
|
||||
except Exception:
|
||||
pass
|
||||
shp.line.fill.background()
|
||||
return shp
|
||||
|
||||
|
||||
def text(slide, x, y, w, h, runs, size=14, bold=False, color=BLACK,
|
||||
align=PP_ALIGN.LEFT, font=FONT, anchor=MSO_ANCHOR.TOP, leading=1.0,
|
||||
space_after=0):
|
||||
@@ -189,6 +209,7 @@ def header(slide, kicker, title, dark=False):
|
||||
size=11, bold=True, color=RED, font=FONT)
|
||||
text(slide, 0.55, 0.75, 12.2, 0.75, title,
|
||||
size=30, bold=True, color=WHITE if dark else BLACK)
|
||||
grad_rect(slide, 0.57, 1.42, 1.9, 0.045, DARKRED, RED, angle=0.0)
|
||||
logo = LOGO_RED if not dark else LOGO_WHITE
|
||||
if os.path.exists(logo):
|
||||
slide.shapes.add_picture(logo, Inches(12.35), Inches(0.25), Inches(0.62), Inches(0.76))
|
||||
@@ -307,7 +328,8 @@ make_architecture_diagram(ARCH)
|
||||
# FOLIE 1 — Titel (dunkel)
|
||||
# ===========================================================================
|
||||
s = new_slide(BLACK)
|
||||
rect(s, 9.0, 0, 4.333, 7.5, RED, rounded=False)
|
||||
grad_rect(s, 9.0, 0, 4.333, 7.5, RED, DARKRED, angle=90.0)
|
||||
rect(s, 8.94, 0, 0.06, 7.5, BLACK) # weicher Übergang Anthrazit -> Rot-Panel
|
||||
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)
|
||||
@@ -324,8 +346,9 @@ agenda = [
|
||||
"3. YAML, Playbooks & Ad-hoc",
|
||||
"4. Module, Jinja2 & Facts",
|
||||
"5. Variablen & Auflösung",
|
||||
"6. FQCN & Collections",
|
||||
"7. Rollen & Praxis",
|
||||
"6. Ansible Vault (Secrets)",
|
||||
"7. FQCN & Collections",
|
||||
"8. Rollen & Praxis",
|
||||
]
|
||||
text(s, 9.5, 2.15, 3.3, 4.0, agenda, size=14, color=WHITE, leading=1.5)
|
||||
|
||||
@@ -335,7 +358,7 @@ text(s, 9.5, 2.15, 3.3, 4.0, agenda, size=14, color=WHITE, leading=1.5)
|
||||
# ===========================================================================
|
||||
s = new_slide(LIGHT)
|
||||
header(s, "Grundlagen", "Was ist Ansible?")
|
||||
rect(s, 0.55, 1.55, 8.0, 1.15, BLACK, rounded=True, radius=0.08)
|
||||
grad_rect(s, 0.55, 1.55, 8.0, 1.15, BLACK, DARKRED, angle=0.0, rounded=True, radius=0.08)
|
||||
text(s, 0.85, 1.75, 7.4, 0.75,
|
||||
"Ansible ist ein Open-Source-Tool zur Automatisierung von IT-Aufgaben — "
|
||||
"Provisionierung, Konfigurationsmanagement und Anwendungs-Deployment.",
|
||||
@@ -705,34 +728,39 @@ text(s, 0.55, 1.5, 12.2, 0.7,
|
||||
("setup", {"font": FONT_MONO, "color": DARKRED}),
|
||||
(", standardmäßig ", {}),
|
||||
("gather_facts: true", {"font": FONT_MONO, "color": DARKRED}),
|
||||
(".", {})]],
|
||||
(". Zugriff neu in ", {}),
|
||||
("ansible_facts['…']", {"font": FONT_MONO, "color": DARKRED, "bold": True}),
|
||||
(" — ohne ", {}),
|
||||
("ansible_", {"font": FONT_MONO, "color": DARKRED}),
|
||||
("-Präfix.", {})]],
|
||||
size=13, color=BLACK, leading=1.15)
|
||||
|
||||
# Links: Facts als einzelne Spalte (breite Schlüssel-Spalte -> kein Umbruch)
|
||||
text(s, 0.55, 2.4, 6.8, 0.3, "WAS MAN AUSLESEN KANN", size=11, bold=True, color=RED)
|
||||
kv_rows(s, 0.55, 2.9, 6.8, [
|
||||
("ansible_os_family", "Betriebssystem-Familie"),
|
||||
("ansible_distribution", "z.B. Ubuntu, Debian"),
|
||||
("ansible_hostname", "Hostname des Systems"),
|
||||
("ansible_default_ipv4.address", "IP-Adresse"),
|
||||
("ansible_memtotal_mb", "Arbeitsspeicher (MB)"),
|
||||
("ansible_processor_vcpus", "CPU-Kerne"),
|
||||
], key_w=3.5, name_size=12, desc_size=11, gap=0.6)
|
||||
("ansible_facts['os_family']", "Betriebssystem-Familie"),
|
||||
("ansible_facts['distribution']", "z.B. Ubuntu, Debian"),
|
||||
("ansible_facts['hostname']", "Hostname des Systems"),
|
||||
("ansible_facts['default_ipv4']", ".['address'] = IP-Adresse"),
|
||||
("ansible_facts['memtotal_mb']", "Arbeitsspeicher (MB)"),
|
||||
("ansible_facts['processor_vcpus']", "CPU-Kerne"),
|
||||
], key_w=3.35, name_size=11.5, desc_size=11, gap=0.6)
|
||||
|
||||
# Rechts: ein einzelner, klarer Code-Block (Zugriff + Custom Facts)
|
||||
code_block(s, 7.55, 2.4, 5.2, [
|
||||
"# Zugriff im Playbook",
|
||||
"# Zugriff im Playbook (neu, empfohlen)",
|
||||
"- name: OS anzeigen",
|
||||
" ansible.builtin.debug:",
|
||||
" msg: \"{{ ansible_distribution }}\"",
|
||||
" msg: \"{{ ansible_facts['distribution'] }}\"",
|
||||
"",
|
||||
"# Fakten deaktivieren (schneller)",
|
||||
"gather_facts: false",
|
||||
"",
|
||||
"# Eigene Facts setzen:",
|
||||
"# Datei: /etc/ansible/facts.d/app.fact",
|
||||
"# Abruf: {{ ansible_local.app.version }}",
|
||||
], font_size=11, title="Zugriff & Custom Facts")
|
||||
"# Abruf: {{ ansible_facts['ansible_local'] }}",
|
||||
"# ['app']['version']",
|
||||
], font_size=10.5, title="Zugriff & Custom Facts")
|
||||
footer(s)
|
||||
|
||||
|
||||
@@ -783,11 +811,84 @@ footer(s)
|
||||
|
||||
|
||||
# ===========================================================================
|
||||
# FOLIE 14 — FQCN (Definition)
|
||||
# FOLIE 14 — Ansible Vault (Konzept)
|
||||
# ===========================================================================
|
||||
s = new_slide(WHITE)
|
||||
header(s, "Vault", "Ansible Vault — Secrets verschlüsseln")
|
||||
grad_rect(s, 0.55, 1.55, 12.2, 1.0, BLACK, DARKRED, angle=0.0, rounded=True, radius=0.08)
|
||||
text(s, 0.85, 1.72, 11.6, 0.7,
|
||||
"Ansible Vault verschlüsselt sensible Daten — Passwörter, API-Keys, ganze "
|
||||
"Dateien — mit AES-256. Verschlüsseltes kann gefahrlos im Git-Repository "
|
||||
"liegen; ohne Vault-Passwort bleibt der Inhalt unlesbar.",
|
||||
size=13.5, color=WHITE, leading=1.15)
|
||||
vault_cards = [
|
||||
("Ganze Dateien", "Mit ansible-vault create / encrypt / edit wird eine "
|
||||
"komplette YAML-Datei verschlüsselt — z.B. group_vars/all.yml."),
|
||||
("Einzelne Variablen", "Mit ansible-vault encrypt_string entsteht ein "
|
||||
"!vault-Block im Klartext-File — Ansible löst ihn automatisch auf."),
|
||||
("AES-256 + Passwort", "Der Schlüssel ist dein Vault-Passwort. Ohne es "
|
||||
"ist der Chiffre-Text wertlos — auch für Git-Reader."),
|
||||
("Sicher im Git", "Chiffrierte Dateien sind committbar. Nur das "
|
||||
"Passwort (bzw. Passwort-Datei) hältst du aus dem Repo fern."),
|
||||
]
|
||||
for i, (t, d) in enumerate(vault_cards):
|
||||
col = i % 2; row = i // 2
|
||||
card(s, 0.55 + col * 6.2, 2.95 + row * 1.75, 5.95, 1.55, "•", t, d)
|
||||
text(s, 0.55, 6.5, 12.2, 0.35,
|
||||
[[("Erkennungs-Merkmal: ", {"bold": True}),
|
||||
("$ANSIBLE_VAULT;1.1;AES256", {"font": FONT_MONO, "color": DARKRED, "bold": True}),
|
||||
(" — dieser Header in der ersten Zeile markiert jede verschlüsselte Datei.", {})]],
|
||||
size=11.5, color=GRAY)
|
||||
footer(s)
|
||||
|
||||
|
||||
# ===========================================================================
|
||||
# FOLIE 15 — Ansible Vault (Praxis: Variable & Datei)
|
||||
# ===========================================================================
|
||||
s = new_slide(WHITE)
|
||||
header(s, "Vault", "Vault in der Praxis — Variable & Datei")
|
||||
text(s, 0.55, 1.55, 12.2, 0.4,
|
||||
"Zwei typische Fälle: eine einzelne Variable als !vault-Block — oder eine "
|
||||
"ganze Datei komplett verschlüsselt.",
|
||||
size=12.5, color=BLACK, leading=1.15)
|
||||
code_block(s, 0.55, 2.15, 6.0, [
|
||||
"# Variable verschlüsseln",
|
||||
"ansible-vault encrypt_string \\",
|
||||
" 'S3kret!' --name db_password",
|
||||
"",
|
||||
"# Ergebnis — in group_vars/all.yml:",
|
||||
"db_password: !vault |",
|
||||
" $ANSIBLE_VAULT;1.1;AES256",
|
||||
" 36623063653163316238...",
|
||||
"",
|
||||
"# Nutzung wie jede Variable:",
|
||||
"msg: \"PW: {{ db_password }}\"",
|
||||
], font_size=10, title="Einzelne Variable")
|
||||
code_block(s, 6.85, 2.15, 5.95, [
|
||||
"# Neue verschlüsselte Datei anlegen",
|
||||
"ansible-vault create secrets.yml",
|
||||
"",
|
||||
"# Bestehende Datei verschlüsseln",
|
||||
"ansible-vault encrypt secrets.yml",
|
||||
"",
|
||||
"# Ansehen / bearbeiten / entschlüsseln",
|
||||
"ansible-vault view secrets.yml",
|
||||
"ansible-vault edit secrets.yml",
|
||||
"ansible-vault decrypt secrets.yml",
|
||||
], font_size=10, title="Ganze Datei")
|
||||
code_block(s, 0.55, 5.35, 12.25, [
|
||||
"ansible-playbook site.yml --ask-vault-pass",
|
||||
"ansible-playbook site.yml --vault-password-file ~/.vault_pass",
|
||||
], font_size=11, title="Playbook ausführen — Vault-Passwort nötig")
|
||||
footer(s)
|
||||
|
||||
|
||||
# ===========================================================================
|
||||
# FOLIE 16 — 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)
|
||||
rect(s, 0.55, 1.55, 12.2, 0.95, REDTINT, 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.", {})]],
|
||||
@@ -813,7 +914,7 @@ footer(s)
|
||||
|
||||
|
||||
# ===========================================================================
|
||||
# FOLIE 15 — FQCN (Beispiele & Warum)
|
||||
# FOLIE 17 — FQCN (Beispiele & Warum)
|
||||
# ===========================================================================
|
||||
s = new_slide(WHITE)
|
||||
header(s, "FQCN", "FQCN in der Praxis")
|
||||
@@ -834,7 +935,7 @@ for fqcn, d in ex:
|
||||
text(s, 4.45, yy + 0.1, 2.6, 0.3, d, size=11.5, color=BLACK)
|
||||
yy += 0.62
|
||||
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)
|
||||
rect(s, 7.35, 2.1, 5.45, 4.35, REDTINT, 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}),
|
||||
@@ -852,11 +953,11 @@ footer(s)
|
||||
|
||||
|
||||
# ===========================================================================
|
||||
# FOLIE 16 — Collections (Definition)
|
||||
# FOLIE 18 — Collections (Definition)
|
||||
# ===========================================================================
|
||||
s = new_slide(LIGHT)
|
||||
header(s, "Collections", "Was sind Collections?")
|
||||
rect(s, 0.55, 1.6, 12.2, 1.1, BLACK, rounded=True, radius=0.08)
|
||||
grad_rect(s, 0.55, 1.6, 12.2, 1.1, BLACK, DARKRED, angle=0.0, rounded=True, radius=0.08)
|
||||
text(s, 0.85, 1.8, 11.6, 0.75,
|
||||
"Eine Collection ist das Verteilungsformat für Ansible-Inhalte. Sie bündelt "
|
||||
"Module, Plugins, Rollen, Playbooks und Dokumentation in einem Paket.",
|
||||
@@ -876,7 +977,7 @@ footer(s)
|
||||
|
||||
|
||||
# ===========================================================================
|
||||
# FOLIE 17 — Collections (Struktur & Galaxy)
|
||||
# FOLIE 19 — Collections (Struktur & Galaxy)
|
||||
# ===========================================================================
|
||||
s = new_slide(WHITE)
|
||||
header(s, "Collections", "Collections nutzen")
|
||||
@@ -919,11 +1020,11 @@ footer(s)
|
||||
|
||||
|
||||
# ===========================================================================
|
||||
# FOLIE 18 — Rollen (Konzept)
|
||||
# FOLIE 20 — Rollen (Konzept)
|
||||
# ===========================================================================
|
||||
s = new_slide(LIGHT)
|
||||
header(s, "Rollen", "Wie funktionieren Rollen?")
|
||||
rect(s, 0.55, 1.6, 12.2, 1.05, BLACK, rounded=True, radius=0.08)
|
||||
grad_rect(s, 0.55, 1.6, 12.2, 1.05, BLACK, DARKRED, angle=0.0, rounded=True, radius=0.08)
|
||||
text(s, 0.85, 1.78, 11.6, 0.75,
|
||||
"Eine Rolle ist eine wiederverwendbare, in sich geschlossene Einheit von "
|
||||
"Aufgaben. Sie kapselt Tasks, Variablen, Templates und Handler zu einer "
|
||||
@@ -942,7 +1043,7 @@ footer(s)
|
||||
|
||||
|
||||
# ===========================================================================
|
||||
# FOLIE 19 — Rollen (Verzeichnisstruktur)
|
||||
# FOLIE 21 — Rollen (Verzeichnisstruktur)
|
||||
# ===========================================================================
|
||||
s = new_slide(WHITE)
|
||||
header(s, "Rollen", "Die Verzeichnisstruktur einer Rolle")
|
||||
@@ -984,7 +1085,7 @@ footer(s)
|
||||
|
||||
|
||||
# ===========================================================================
|
||||
# FOLIE 20 — Praxisbeispiel
|
||||
# FOLIE 22 — Praxisbeispiel
|
||||
# ===========================================================================
|
||||
s = new_slide(LIGHT)
|
||||
header(s, "Praxis", "Alles zusammen: Playbook mit Rolle")
|
||||
@@ -1015,7 +1116,7 @@ footer(s)
|
||||
|
||||
|
||||
# ===========================================================================
|
||||
# FOLIE 21 — Zusammenfassung & Quellen
|
||||
# FOLIE 23 — Zusammenfassung & Quellen
|
||||
# ===========================================================================
|
||||
s = new_slide(LIGHT)
|
||||
header(s, "Fazit", "Zusammenfassung")
|
||||
@@ -1026,6 +1127,7 @@ takeaways = [
|
||||
("Ad-hoc", "ansible <hosts> -m <modul> für schnelle Einzelaktionen."),
|
||||
("Facts", "Systeminfos werden automatisch gesammelt (gather_facts)."),
|
||||
("Variablen", "Auflösung nach Präzedenz — Extra-Vars gewinnen, Defaults verlieren."),
|
||||
("Vault", "Sensible Daten mit AES-256 verschlüsseln — Variable (!vault) oder ganze Datei."),
|
||||
("FQCN", "Eindeutige Modul-Referenz: namespace.collection.modul."),
|
||||
("Collections", "Pakete mit Modulen, Rollen & Plugins (Galaxy)."),
|
||||
("Rollen", "Wiederverwendbare, gekapselte Aufgaben-Einheiten."),
|
||||
@@ -1035,7 +1137,7 @@ for t, d in takeaways:
|
||||
text(s, 0.75, yy, 2.0, 0.4, t, size=13, bold=True, color=RED)
|
||||
text(s, 2.85, yy + 0.02, 6.7, 0.5, d, size=11.5, color=BLACK, leading=1.05)
|
||||
yy += 0.52
|
||||
rect(s, 9.8, 1.7, 2.95, 4.6, LIGHT, line=BORDER, line_w=1.0, rounded=True, radius=0.06)
|
||||
rect(s, 9.8, 1.7, 2.95, 4.6, REDTINT, line=BORDER, line_w=1.0, rounded=True, radius=0.06)
|
||||
if os.path.exists(LOGO_RED):
|
||||
s.shapes.add_picture(LOGO_RED, Inches(10.35), Inches(1.95), Inches(1.2), Inches(1.48))
|
||||
text(s, 10.05, 3.6, 2.4, 0.3, "QUELLEN", size=11, bold=True, color=RED, align=PP_ALIGN.CENTER)
|
||||
@@ -1049,7 +1151,7 @@ footer(s)
|
||||
# ---------------------------------------------------------------------------
|
||||
# Speichern
|
||||
# ---------------------------------------------------------------------------
|
||||
OUT = os.path.join(BASE, "ansible_praesentation.pptx")
|
||||
OUT = os.path.join(DOCS, "ansible_praesentation.pptx")
|
||||
prs.save(OUT)
|
||||
print(f"OK — gespeichert: {OUT}")
|
||||
print(f"Folien: {len(prs.slides)}")
|
||||
|
||||
Reference in New Issue
Block a user