Anpassung für vault hinzugefügt

This commit is contained in:
2026-10-05 11:54:31 +02:00
parent 5fbd0c1a61
commit 3ceae1bf83
10 changed files with 248 additions and 77 deletions
+1 -1
View File
@@ -7,7 +7,7 @@ demonstriert:
- **Variablen-Vergabe** mit Präzedenz (defaults → vars → group_vars → host_vars) - **Variablen-Vergabe** mit Präzedenz (defaults → vars → group_vars → host_vars)
- **Templating** mit Jinja2 (`.j2`-Dateien, Schleifen, Filter) - **Templating** mit Jinja2 (`.j2`-Dateien, Schleifen, Filter)
- **FQCN** (`ansible.builtin.*`) - **FQCN** (`ansible.builtin.*`)
- **Facts** (`ansible_distribution`, `ansible_hostname`, …) - **Facts** (`ansible_facts['distribution']`, `ansible_facts['hostname']`, …)
- **Handler** (`notify` → Dienst neu starten) - **Handler** (`notify` → Dienst neu starten)
--- ---
+1 -1
View File
@@ -4,7 +4,7 @@
- name: Betriebssystem ausgeben (Facts nutzen) - name: Betriebssystem ausgeben (Facts nutzen)
ansible.builtin.debug: ansible.builtin.debug:
msg: "Läuft auf {{ ansible_distribution }} {{ ansible_distribution_version }}" msg: "Läuft auf {{ ansible_facts['distribution'] }} {{ ansible_facts['distribution_version'] }}"
- name: Pakete installieren - name: Pakete installieren
ansible.builtin.apt: ansible.builtin.apt:
@@ -6,7 +6,7 @@
</head> </head>
<body> <body>
<h1>{{ app_name }}</h1> <h1>{{ app_name }}</h1>
<p>Betriebssystem: {{ ansible_distribution }} {{ ansible_distribution_version }}</p> <p>Betriebssystem: {{ ansible_facts['distribution'] }} {{ ansible_facts['distribution_version'] }}</p>
<p>Installierte Pakete:</p> <p>Installierte Pakete:</p>
<ul> <ul>
@@ -16,6 +16,6 @@ http {
index index.html; index index.html;
# Fact des Zielsystems wird hier aufgelöst: # Fact des Zielsystems wird hier aufgelöst:
access_log /var/log/nginx/{{ ansible_hostname }}.access.log; access_log /var/log/nginx/{{ ansible_facts['hostname'] }}.access.log;
} }
} }
Binary file not shown.
+80 -17
View File
@@ -1,6 +1,6 @@
# Ansible — Syntax & Variablen-Handout # Ansible — Syntax & Variablen-Handout
Kompakte Referenz zu YAML-Syntax, Ad-hoc-Befehlen, Jinja2, Facts, Variablen-Auflösung, FQCN und ansible.cfg. Kompakte Referenz zu YAML-Syntax, Ad-hoc-Befehlen, Jinja2, Facts, Variablen-Auflösung, Ansible Vault, FQCN und ansible.cfg.
--- ---
@@ -119,25 +119,31 @@ server {
Ansible sammelt automatisch **Facts** (Systeminformationen) über jeden Host — Ansible sammelt automatisch **Facts** (Systeminformationen) über jeden Host —
über das Modul `setup`, standardmäßig `gather_facts: true`. über das Modul `setup`, standardmäßig `gather_facts: true`.
> **Aktuelle Schreibweise:** Facts werden über das Dictionary
> `ansible_facts` gelesen — **ohne** `ansible_`-Präfix:
> `ansible_facts['distribution']` statt `ansible_distribution`. Die alten
> `ansible_*`-Top-Level-Variablen sind veraltet (Deprecated) und werden
> standardmäßig nicht mehr injiziert.
Häufige Facts: Häufige Facts:
| Fact | Bedeutung | | Fact | Bedeutung |
|---------------------------------|-------------------------------| |-----------------------------------|-------------------------------|
| `ansible_os_family` | OS-Familie (Debian, RedHat) | | `ansible_facts['os_family']` | OS-Familie (Debian, RedHat) |
| `ansible_distribution` | z.B. Ubuntu, CentOS, Debian | | `ansible_facts['distribution']` | z.B. Ubuntu, CentOS, Debian |
| `ansible_distribution_version` | Version (z.B. 22.04) | | `ansible_facts['distribution_version']` | Version (z.B. 22.04) |
| `ansible_hostname` | Hostname des Systems | | `ansible_facts['hostname']` | Hostname des Systems |
| `ansible_default_ipv4.address` | IP-Adresse | | `ansible_facts['default_ipv4']['address']` | IP-Adresse |
| `ansible_architecture` | CPU-Architektur (x86_64) | | `ansible_facts['architecture']` | CPU-Architektur (x86_64) |
| `ansible_memtotal_mb` | RAM in MB | | `ansible_facts['memtotal_mb']` | RAM in MB |
| `ansible_processor_vcpus` | Anzahl CPU-Kerne | | `ansible_facts['processor_vcpus']`| Anzahl CPU-Kerne |
Zugriff im Playbook: Zugriff im Playbook:
```yaml ```yaml
- name: OS anzeigen - name: OS anzeigen
ansible.builtin.debug: ansible.builtin.debug:
msg: "{{ ansible_distribution }} {{ ansible_distribution_version }}" msg: "{{ ansible_facts['distribution'] }} {{ ansible_facts['distribution_version'] }}"
``` ```
Eigene Facts (Custom Facts) setzen: Eigene Facts (Custom Facts) setzen:
@@ -148,7 +154,8 @@ Eigene Facts (Custom Facts) setzen:
# Inhalt: # Inhalt:
# [app] # [app]
# version=1.2.3 # version=1.2.3
# Abruf: {{ ansible_local.app.version }} # Abruf (der Name des .fact-Files wird zum Unter-Key):
# {{ ansible_facts['ansible_local']['app']['version'] }}
``` ```
Facts deaktivieren (Performance): Facts deaktivieren (Performance):
@@ -166,13 +173,69 @@ gather_facts: false
| Inventory | `host_vars/`, `group_vars/` | `group_vars/webserver.yml` | | Inventory | `host_vars/`, `group_vars/` | `group_vars/webserver.yml` |
| Playbook | `vars:` / `vars_files:` | `vars: { port: 8080 }` | | Playbook | `vars:` / `vars_files:` | `vars: { port: 8080 }` |
| Rolle | `roles/<rolle>/vars/` + `defaults/`| `vars/main.yml` | | Rolle | `roles/<rolle>/vars/` + `defaults/`| `vars/main.yml` |
| Facts | automatisch gesammelt | `ansible_os_family` | | Facts | automatisch gesammelt | `ansible_facts['os_family']` |
| Laufzeit | `register` / `set_fact` | `register: result` | | Laufzeit | `register` / `set_fact` | `register: result` |
| CLI | Extra-Variablen | `-e "port=8080"` | | CLI | Extra-Variablen | `-e "port=8080"` |
--- ---
## 6. Variablen-Präzedenz (Auflösungs-Reihenfolge) ## 6. Ansible Vault — Secrets verschlüsseln
Ansible Vault verschlüsselt sensible Daten (Passwörter, API-Keys, ganze Dateien)
mit **AES-256**. Der Schlüssel ist dein Vault-Passwort. Jede verschlüsselte
Datei erkennt man an der ersten Zeile: `$ANSIBLE_VAULT;1.1;AES256`.
### Fall A: Eine einzelne Variable verschlüsseln
```bash
ansible-vault encrypt_string 'S3kret!' --name db_password
```
Ausgabe — diesen Block einfach in `group_vars/all.yml` (o.ä.) einfügen:
```yaml
db_password: !vault |
$ANSIBLE_VAULT;1.1;AES256
366230636531633162386130623530653637353436623539...
...weiche Chiffre-Zeilen...
```
Die Datei bleibt sonst Klartext; Ansible erkennt den `!vault`-Block und löst
die Variable beim Lauf automatisch auf — Nutzung wie jede andere Variable:
```yaml
- name: DB-Zugang testen
ansible.builtin.debug:
msg: "Passwort: {{ db_password }}"
```
### Fall B: Eine ganze Datei verschlüsseln
```bash
ansible-vault create secrets.yml # neue verschlüsselte Datei anlegen
ansible-vault encrypt secrets.yml # bestehende Datei verschlüsseln
ansible-vault view secrets.yml # Inhalt ansehen (entschlüsselt anzeigen)
ansible-vault edit secrets.yml # im Editor bearbeiten (bleibt verschlüsselt)
ansible-vault decrypt secrets.yml # wieder entschlüsseln
```
`secrets.yml` enthält danach nur noch Chiffre-Text. Als Inventory-Variable
eingebunden (z.B. `group_vars/all.yml` = Vault-Datei) stehen alle Werte daraus
als ganz normale Variablen zur Verfügung.
### Playbook ausführen
```bash
ansible-playbook site.yml --ask-vault-pass # Passwort interaktiv
ansible-playbook site.yml --vault-password-file ~/.vault_pass
```
Alternativ in `ansible.cfg`: `[defaults] vault_password_file = ~/.vault_pass`
> **Git-Praxis:** Verschlüsselte Dateien dürfen ins Repo. Das Vault-Passwort
> (bzw. die Passwort-Datei) NIEMALS committen — z.B. über `.gitignore` schützen.
## 7. Variablen-Präzedenz (Auflösungs-Reihenfolge)
Ist dieselbe Variable an mehreren Stellen definiert, gewinnt die mit der Ist dieselbe Variable an mehreren Stellen definiert, gewinnt die mit der
**höchsten** Priorität (oben = gewinnt): **höchsten** Priorität (oben = gewinnt):
@@ -189,7 +252,7 @@ Ist dieselbe Variable an mehreren Stellen definiert, gewinnt die mit der
--- ---
## 7. Module & FQCN ## 8. Module & FQCN
FQCN = **Fully Qualified Collection Name** — `namespace.collection.modul`. FQCN = **Fully Qualified Collection Name** — `namespace.collection.modul`.
@@ -210,7 +273,7 @@ ansible.builtin.apt:
--- ---
## 8. ansible.cfg — Konfiguration ## 9. ansible.cfg — Konfiguration
INI-Datei, die Ansible global steuert. Ansible nutzt die **erste** gefundene INI-Datei, die Ansible global steuert. Ansible nutzt die **erste** gefundene
Datei (kein Zusammenführen): Datei (kein Zusammenführen):
@@ -257,7 +320,7 @@ pipelining = True
--- ---
## 9. Vollständiges Beispiel ## 10. Vollständiges Beispiel
**Playbook** (`deploy.yml`): **Playbook** (`deploy.yml`):
+23 -17
View File
@@ -9,10 +9,12 @@ lauffähigen Beispiel-Projekt. Alles in Python generiert und reproduzierbar.
``` ```
ansible_präsentation/ ansible_präsentation/
├── ansible_praesentation.pptx # Die fertige Präsentation (21 Folien, 16:9)
├── create_presentation.py # Python-Skript, das die .pptx erzeugt ├── create_presentation.py # Python-Skript, das die .pptx erzeugt
├── handout.md # Handout (Markdown-Quelle) ├── README.md # Diese Übersicht
├── handout.docx # Handout (druckbar/editierbar, für OnlyOffice) ├── Dokumentation/
│ ├── ansible_praesentation.pptx # Die fertige Präsentation (23 Folien, 16:9)
│ ├── handout.md # Handout (Markdown-Quelle)
│ └── handout.docx # Handout (druckbar/editierbar, für OnlyOffice)
├── assets/ ├── assets/
│ ├── ansible_mark_red.png # Ansible-Logo (rot) — Quelle: Wikimedia Commons │ ├── ansible_mark_red.png # Ansible-Logo (rot) — Quelle: Wikimedia Commons
│ ├── ansible_mark_white.png # Ansible-Logo (weiß) │ ├── ansible_mark_white.png # Ansible-Logo (weiß)
@@ -25,7 +27,7 @@ ansible_präsentation/
## 1. Die Präsentation (`ansible_praesentation.pptx`) ## 1. Die Präsentation (`ansible_praesentation.pptx`)
21 Folien, 16:9, in den Ansible-Brandfarben (Rot `#EE0000`, Anthrazit `#1A1918`). 23 Folien, 16:9, in den Ansible-Brandfarben (Rot `#EE0000`, Anthrazit `#1A1918`).
| # | Titel | Inhalt | | # | Titel | Inhalt |
|---|-------|--------| |---|-------|--------|
@@ -42,14 +44,16 @@ ansible_präsentation/
| 11 | Jinja2 | `{{ variable }}`, Filter, `.j2`-Templates | | 11 | Jinja2 | `{{ variable }}`, Filter, `.j2`-Templates |
| 12 | Gather Facts | Facts auslesen, Custom Facts, `gather_facts` | | 12 | Gather Facts | Facts auslesen, Custom Facts, `gather_facts` |
| 13 | Variablen & Präzedenz | Quellen + Reihenfolge (wer gewinnt) | | 13 | Variablen & Präzedenz | Quellen + Reihenfolge (wer gewinnt) |
| 14 | FQCN (Definition) | `namespace.collection.modul` | | 14 | Ansible Vault (Konzept) | AES-256, `$ANSIBLE_VAULT`-Header, sicher in Git |
| 15 | FQCN (Praxis) | Beispiele + Warum | | 15 | Ansible Vault (Praxis) | `encrypt_string` (!vault-Variable) + ganze Datei (`create`/`encrypt`/`view`/`edit`/`decrypt`), `--ask-vault-pass` |
| 16 | Collections | Was sie sind (6 Bestandteile) | | 16 | FQCN (Definition) | `namespace.collection.modul` |
| 17 | Collections nutzen | Galaxy, Installation, Struktur | | 17 | FQCN (Praxis) | Beispiele + Warum |
| 18 | Rollen (Konzept) | Wiederverwendbarkeit, Kapselung | | 18 | Collections | Was sie sind (6 Bestandteile) |
| 19 | Rollen (Struktur) | `roles/webserver/` Verzeichnisbaum | | 19 | Collections nutzen | Galaxy, Installation, Struktur |
| 20 | Praxisbeispiel | Playbook mit Rolle + Variablen | | 20 | Rollen (Konzept) | Wiederverwendbarkeit, Kapselung |
| 21 | Zusammenfassung | Key-Takeaways + Quellen | | 21 | Rollen (Struktur) | `roles/webserver/` Verzeichnisbaum |
| 22 | Praxisbeispiel | Playbook mit Rolle + Variablen |
| 23 | Zusammenfassung | Key-Takeaways + Quellen |
**Design-Hinweis:** Die Präsentation nutzt die Schriftarten **Carlito** (Body) **Design-Hinweis:** Die Präsentation nutzt die Schriftarten **Carlito** (Body)
und **DejaVu Sans Mono** (Code), da Calibri/Consolas auf Linux oft fehlen und und **DejaVu Sans Mono** (Code), da Calibri/Consolas auf Linux oft fehlen und
@@ -87,13 +91,15 @@ Kompakte Referenz mit:
3. Jinja2 (Variablen auflösen, Filter, `.j2`) 3. Jinja2 (Variablen auflösen, Filter, `.j2`)
4. Gather Facts 4. Gather Facts
5. Wo Variablen definiert werden 5. Wo Variablen definiert werden
6. Variablen-Präzedenz (Auflösungs-Reihenfolge) 6. Ansible Vault (Variable per `!vault` + ganze Datei)
7. Module & FQCN 7. Variablen-Präzedenz (Auflösungs-Reihenfolge)
8. ansible.cfg (Suchreihenfolge + Parameter) 8. Module & FQCN
9. Vollständiges Beispiel 9. ansible.cfg (Suchreihenfolge + Parameter)
10. Vollständiges Beispiel
Das `.docx` wird aus dem `.md` per pandoc erzeugt: Das `.docx` wird aus dem `.md` per pandoc erzeugt:
```bash ```bash
cd Dokumentation
pandoc handout.md -o handout.docx pandoc handout.md -o handout.docx
``` ```
@@ -116,7 +122,7 @@ Die Struktur zeigt:
- `roles/webserver/` mit tasks, handlers, templates, defaults, vars, meta - `roles/webserver/` mit tasks, handlers, templates, defaults, vars, meta
- Variablen-Präzedenz: `defaults` (80) → `host_vars` (8080) → `-e` (gewinnt) - Variablen-Präzedenz: `defaults` (80) → `host_vars` (8080) → `-e` (gewinnt)
- Jinja2-Templates (`nginx.conf.j2`, `index.html.j2` mit Schleife + Filter) - Jinja2-Templates (`nginx.conf.j2`, `index.html.j2` mit Schleife + Filter)
- Facts (`ansible_distribution`, `ansible_hostname`, …) - Facts (`ansible_facts['distribution']`, `ansible_facts['hostname']`, …)
- FQCN (`ansible.builtin.*`) - FQCN (`ansible.builtin.*`)
- `connection: local` — läuft direkt auf dem Rechner, kein SSH (localhost ist kein echter Host) - `connection: local` — läuft direkt auf dem Rechner, kein SSH (localhost ist kein echter Host)
+134 -32
View File
@@ -2,7 +2,7 @@
""" """
Moderne Ansible-Präsentation — vollständiger Generator (v3). 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 Fonts: Carlito (Body) + DejaVu Sans Mono (Code) — auf dem Zielsystem installiert
und von OnlyOffice korrekt gerendert (kein Font-Substitution-Bruch). und von OnlyOffice korrekt gerendert (kein Font-Substitution-Bruch).
@@ -11,6 +11,7 @@ Behandelt:
- YAML-Syntax, Playbooks, Module, Ad-hoc-Befehle - YAML-Syntax, Playbooks, Module, Ad-hoc-Befehle
- Jinja2 (Templating) und Gather Facts - Jinja2 (Templating) und Gather Facts
- Variablen-Auflösung (Präzedenz) - Variablen-Auflösung (Präzedenz)
- Ansible Vault (verschlüsselte Variablen & Dateien)
- FQCN (Fully Qualified Collection Name) - FQCN (Fully Qualified Collection Name)
- Collections - Collections
- Rollen (Roles) - Rollen (Roles)
@@ -38,8 +39,10 @@ from pptx.dml.color import RGBColor
# Pfade & Farben # Pfade & Farben
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
BASE = os.path.dirname(os.path.abspath(__file__)) BASE = os.path.dirname(os.path.abspath(__file__))
DOCS = os.path.join(BASE, "Dokumentation")
ASSETS = os.path.join(BASE, "assets") ASSETS = os.path.join(BASE, "assets")
os.makedirs(ASSETS, exist_ok=True) os.makedirs(ASSETS, exist_ok=True)
os.makedirs(DOCS, exist_ok=True)
LOGO_RED = os.path.join(ASSETS, "ansible_mark_red.png") LOGO_RED = os.path.join(ASSETS, "ansible_mark_red.png")
LOGO_WHITE = os.path.join(ASSETS, "ansible_mark_white.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) RED = RGBColor(0xEE, 0x00, 0x00)
DARKRED = RGBColor(0xB0, 0x00, 0x00) DARKRED = RGBColor(0xB0, 0x00, 0x00)
WHITE = RGBColor(0xFF, 0xFF, 0xFF) 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) CARD = RGBColor(0xFF, 0xFF, 0xFF)
GRAY = RGBColor(0x55, 0x55, 0x55) # dunkler für bessere Lesbarkeit GRAY = RGBColor(0x55, 0x55, 0x55) # dunkler für bessere Lesbarkeit
MIDGRAY = RGBColor(0x8A, 0x8A, 0x8A) 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 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, 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, align=PP_ALIGN.LEFT, font=FONT, anchor=MSO_ANCHOR.TOP, leading=1.0,
space_after=0): space_after=0):
@@ -189,6 +209,7 @@ def header(slide, kicker, title, dark=False):
size=11, bold=True, color=RED, font=FONT) size=11, bold=True, color=RED, font=FONT)
text(slide, 0.55, 0.75, 12.2, 0.75, title, text(slide, 0.55, 0.75, 12.2, 0.75, title,
size=30, bold=True, color=WHITE if dark else BLACK) 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 logo = LOGO_RED if not dark else LOGO_WHITE
if os.path.exists(logo): if os.path.exists(logo):
slide.shapes.add_picture(logo, Inches(12.35), Inches(0.25), Inches(0.62), Inches(0.76)) 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) # FOLIE 1 — Titel (dunkel)
# =========================================================================== # ===========================================================================
s = new_slide(BLACK) 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): if os.path.exists(LOGO_WHITE):
s.shapes.add_picture(LOGO_WHITE, Inches(0.9), Inches(1.35), Inches(2.1), Inches(2.59)) 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.15, 7.5, 0.4, "MODERNE IT-AUTOMATISIERUNG", size=14, bold=True, color=RED)
@@ -324,8 +346,9 @@ agenda = [
"3. YAML, Playbooks & Ad-hoc", "3. YAML, Playbooks & Ad-hoc",
"4. Module, Jinja2 & Facts", "4. Module, Jinja2 & Facts",
"5. Variablen & Auflösung", "5. Variablen & Auflösung",
"6. FQCN & Collections", "6. Ansible Vault (Secrets)",
"7. Rollen & Praxis", "7. FQCN & Collections",
"8. Rollen & Praxis",
] ]
text(s, 9.5, 2.15, 3.3, 4.0, agenda, size=14, color=WHITE, leading=1.5) 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) s = new_slide(LIGHT)
header(s, "Grundlagen", "Was ist Ansible?") 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, text(s, 0.85, 1.75, 7.4, 0.75,
"Ansible ist ein Open-Source-Tool zur Automatisierung von IT-Aufgaben — " "Ansible ist ein Open-Source-Tool zur Automatisierung von IT-Aufgaben — "
"Provisionierung, Konfigurationsmanagement und Anwendungs-Deployment.", "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}), ("setup", {"font": FONT_MONO, "color": DARKRED}),
(", standardmäßig ", {}), (", standardmäßig ", {}),
("gather_facts: true", {"font": FONT_MONO, "color": DARKRED}), ("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) size=13, color=BLACK, leading=1.15)
# Links: Facts als einzelne Spalte (breite Schlüssel-Spalte -> kein Umbruch) # 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) 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, [ kv_rows(s, 0.55, 2.9, 6.8, [
("ansible_os_family", "Betriebssystem-Familie"), ("ansible_facts['os_family']", "Betriebssystem-Familie"),
("ansible_distribution", "z.B. Ubuntu, Debian"), ("ansible_facts['distribution']", "z.B. Ubuntu, Debian"),
("ansible_hostname", "Hostname des Systems"), ("ansible_facts['hostname']", "Hostname des Systems"),
("ansible_default_ipv4.address", "IP-Adresse"), ("ansible_facts['default_ipv4']", ".['address'] = IP-Adresse"),
("ansible_memtotal_mb", "Arbeitsspeicher (MB)"), ("ansible_facts['memtotal_mb']", "Arbeitsspeicher (MB)"),
("ansible_processor_vcpus", "CPU-Kerne"), ("ansible_facts['processor_vcpus']", "CPU-Kerne"),
], key_w=3.5, name_size=12, desc_size=11, gap=0.6) ], key_w=3.35, name_size=11.5, desc_size=11, gap=0.6)
# Rechts: ein einzelner, klarer Code-Block (Zugriff + Custom Facts) # Rechts: ein einzelner, klarer Code-Block (Zugriff + Custom Facts)
code_block(s, 7.55, 2.4, 5.2, [ code_block(s, 7.55, 2.4, 5.2, [
"# Zugriff im Playbook", "# Zugriff im Playbook (neu, empfohlen)",
"- name: OS anzeigen", "- name: OS anzeigen",
" ansible.builtin.debug:", " ansible.builtin.debug:",
" msg: \"{{ ansible_distribution }}\"", " msg: \"{{ ansible_facts['distribution'] }}\"",
"", "",
"# Fakten deaktivieren (schneller)", "# Fakten deaktivieren (schneller)",
"gather_facts: false", "gather_facts: false",
"", "",
"# Eigene Facts setzen:", "# Eigene Facts setzen:",
"# Datei: /etc/ansible/facts.d/app.fact", "# Datei: /etc/ansible/facts.d/app.fact",
"# Abruf: {{ ansible_local.app.version }}", "# Abruf: {{ ansible_facts['ansible_local'] }}",
], font_size=11, title="Zugriff & Custom Facts") "# ['app']['version']",
], font_size=10.5, title="Zugriff & Custom Facts")
footer(s) 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) s = new_slide(WHITE)
header(s, "FQCN", "FQCN — Fully Qualified Collection Name") 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, text(s, 0.85, 1.77, 11.6, 0.55,
[[("FQCN = ", {"bold": True, "color": RED}), [[("FQCN = ", {"bold": True, "color": RED}),
("eindeutige, vollständige Referenz auf ein Modul oder Plugin.", {})]], ("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) s = new_slide(WHITE)
header(s, "FQCN", "FQCN in der Praxis") 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) text(s, 4.45, yy + 0.1, 2.6, 0.3, d, size=11.5, color=BLACK)
yy += 0.62 yy += 0.62
text(s, 7.35, 1.6, 5.4, 0.4, "WARUM FQCN?", size=11, bold=True, color=RED) 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, [ text(s, 7.65, 2.35, 4.9, 3.9, [
[("Seit Ansible 2.10 sind Module in ", {}), [("Seit Ansible 2.10 sind Module in ", {}),
("Collections", {"bold": True}), ("Collections", {"bold": True}),
@@ -852,11 +953,11 @@ footer(s)
# =========================================================================== # ===========================================================================
# FOLIE 16 — Collections (Definition) # FOLIE 18 — Collections (Definition)
# =========================================================================== # ===========================================================================
s = new_slide(LIGHT) s = new_slide(LIGHT)
header(s, "Collections", "Was sind Collections?") 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, text(s, 0.85, 1.8, 11.6, 0.75,
"Eine Collection ist das Verteilungsformat für Ansible-Inhalte. Sie bündelt " "Eine Collection ist das Verteilungsformat für Ansible-Inhalte. Sie bündelt "
"Module, Plugins, Rollen, Playbooks und Dokumentation in einem Paket.", "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) s = new_slide(WHITE)
header(s, "Collections", "Collections nutzen") header(s, "Collections", "Collections nutzen")
@@ -919,11 +1020,11 @@ footer(s)
# =========================================================================== # ===========================================================================
# FOLIE 18 — Rollen (Konzept) # FOLIE 20 — Rollen (Konzept)
# =========================================================================== # ===========================================================================
s = new_slide(LIGHT) s = new_slide(LIGHT)
header(s, "Rollen", "Wie funktionieren Rollen?") 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, text(s, 0.85, 1.78, 11.6, 0.75,
"Eine Rolle ist eine wiederverwendbare, in sich geschlossene Einheit von " "Eine Rolle ist eine wiederverwendbare, in sich geschlossene Einheit von "
"Aufgaben. Sie kapselt Tasks, Variablen, Templates und Handler zu einer " "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) s = new_slide(WHITE)
header(s, "Rollen", "Die Verzeichnisstruktur einer Rolle") header(s, "Rollen", "Die Verzeichnisstruktur einer Rolle")
@@ -984,7 +1085,7 @@ footer(s)
# =========================================================================== # ===========================================================================
# FOLIE 20 — Praxisbeispiel # FOLIE 22 — Praxisbeispiel
# =========================================================================== # ===========================================================================
s = new_slide(LIGHT) s = new_slide(LIGHT)
header(s, "Praxis", "Alles zusammen: Playbook mit Rolle") 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) s = new_slide(LIGHT)
header(s, "Fazit", "Zusammenfassung") header(s, "Fazit", "Zusammenfassung")
@@ -1026,6 +1127,7 @@ takeaways = [
("Ad-hoc", "ansible <hosts> -m <modul> für schnelle Einzelaktionen."), ("Ad-hoc", "ansible <hosts> -m <modul> für schnelle Einzelaktionen."),
("Facts", "Systeminfos werden automatisch gesammelt (gather_facts)."), ("Facts", "Systeminfos werden automatisch gesammelt (gather_facts)."),
("Variablen", "Auflösung nach Präzedenz — Extra-Vars gewinnen, Defaults verlieren."), ("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."), ("FQCN", "Eindeutige Modul-Referenz: namespace.collection.modul."),
("Collections", "Pakete mit Modulen, Rollen & Plugins (Galaxy)."), ("Collections", "Pakete mit Modulen, Rollen & Plugins (Galaxy)."),
("Rollen", "Wiederverwendbare, gekapselte Aufgaben-Einheiten."), ("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, 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) text(s, 2.85, yy + 0.02, 6.7, 0.5, d, size=11.5, color=BLACK, leading=1.05)
yy += 0.52 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): if os.path.exists(LOGO_RED):
s.shapes.add_picture(LOGO_RED, Inches(10.35), Inches(1.95), Inches(1.2), Inches(1.48)) 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) 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 # Speichern
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
OUT = os.path.join(BASE, "ansible_praesentation.pptx") OUT = os.path.join(DOCS, "ansible_praesentation.pptx")
prs.save(OUT) prs.save(OUT)
print(f"OK — gespeichert: {OUT}") print(f"OK — gespeichert: {OUT}")
print(f"Folien: {len(prs.slides)}") print(f"Folien: {len(prs.slides)}")
BIN
View File
Binary file not shown.