Regeln, Standards, Kontextstruktur und Werkzeuge übernommen; 2nd-brain- Inhalte (Stacks, Ansible-Inventar, Architektur, Knowledge) entfernt. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
92 lines
6.1 KiB
Markdown
92 lines
6.1 KiB
Markdown
# Ansible-Standard (verbindlich)
|
||
|
||
> Gilt für alle Plays und Rollen in diesem Projekt. Verallgemeinert aus einem erprobten Homelab-Setup.
|
||
> Vorlagen: [`templates/ansible/`](templates/ansible/). Geheimnisse: `rules/secrets.md`.
|
||
|
||
## 1. Verzeichnislayout
|
||
```
|
||
<repo>/ansible/
|
||
├── .env.sh # setzt alle Pfade + Secret-Store-Variablen → source (bash/zsh)
|
||
├── ansible.cfg # Fact-Cache, become, Log – Pfade aus .env.sh
|
||
├── inv/
|
||
│ ├── <umgebung> # Inventar (INI oder YAML), z. B. prod, lab
|
||
│ ├── group_vars/all/ # globale Variablen (ansible_user, ans_files, Secret-Store-Pfade)
|
||
│ ├── group_vars/<gruppe>.yml
|
||
│ └── host_vars/<host>.yml
|
||
├── playbooks/ # ein Dienst = ein Play; Präambel = Doku
|
||
├── roles/<dienst>/ # Logik: tasks/ handlers/ defaults/ meta/ (keine templates/!)
|
||
└── files/<dienst>/ # alle Templates (*.j2) und Dateien – Rollen holen sie aus $ANS_FILES
|
||
```
|
||
`.env.sh` (interaktiv in der Shell gesourct, setzt `ANSIBLE_*`) ist bewusst etwas anderes als die `.env` der Bash-Scripts.
|
||
|
||
## 2. Aufruf & Umgebung
|
||
- Vor jedem Aufruf: `source ansible/.env.sh`. Pfade **nie** hart codieren: `$ANSIBLE_BASE_PATH`, `$ANS_PLAYDIR`, `$ANS_FILES` (in YAML: `ans_files`).
|
||
- Aufrufe immer: `ansible-playbook $ANS_PLAYDIR/<play>.yml [-e hostlist=…] [--check --diff]`.
|
||
- `.env.sh` setzt fremde `ANSIBLE_*`-Variablen zurück (`unset`), damit kein Kontext eines anderen Repos durchschlägt.
|
||
|
||
| Variable | Zweck |
|
||
|---|---|
|
||
| `ANSIBLE_BASE_PATH` | Basis für alles |
|
||
| `ANSIBLE_CONFIG`, `ANSIBLE_INVENTORY`, `ANSIBLE_ROLES_PATH` | Standard-Ansible-Variablen |
|
||
| `ANS_PLAYDIR` | Playbooks |
|
||
| `ANS_FILES` | Templates/Dateien (YAML: `ans_files`) |
|
||
| `ANS_DEFAULT_HOSTS` | Dokumentation des Standardziels (s. § 3) |
|
||
| `VAULT_ADDR`, `ANSIBLE_HASHI_VAULT_*`, `ANS_VAULT_KV_MOUNT/PATH` | Secret-Store |
|
||
| `ANSIBLE_VAULT_PASSWORD_FILE` | nur wenn Datei existiert (Fallback Ansible Vault) |
|
||
|
||
## 3. Playbooks
|
||
- **Präambel max. 12 Zeilen** im Header-Format (`rules/headers.md`): `@file`, `@brief`, `@author`, `@owner`, `@version`, `@usage` mit nötigen/optionalen `-e`-Variablen, Tags und Voraussetzungen.
|
||
- Ziel immer `hosts: "{{ hostlist | default('<STANDARDHOST>') }}"` – ohne `-e` genau **ein** bekannter, ungefährlicher Host
|
||
(Lab/Test). **Nie** `all` oder eine Produktivgruppe als Default.
|
||
- Ein Dienst = ein Play (`radius.yml`, `dns.yml`). Logik liegt in `roles/<dienst>/`; das Play bindet nur die Rolle ein.
|
||
- Dateinamen: Kleinbuchstaben, `_` statt `-` (`vault_check.yml`).
|
||
- Standard-Hilfsplays je Repo: `mini_check.yml` (Erreichbarkeit, Facts), `vault_check.yml` (Secret-Store erreichbar, nur Schlüsselnamen).
|
||
|
||
## 4. Rollen
|
||
- Rollenname = Dienst. Tasks thematisch teilen: `main.yml` (Ablauf) → `secrets.yml`, `install.yml`, `config.yml`, `verify.yml`.
|
||
- `main.yml` beginnt mit einem **Plattform-Check** (`ansible.builtin.assert` auf `ansible_facts`), Tag `always`.
|
||
- **Templates liegen nicht in der Rolle**, sondern in `files/<dienst>/`; Zugriff über `{{ ans_files }}/<dienst>/…`.
|
||
- Nur Dateien templaten, die wir „besitzen“. Paket-Defaults nicht komplett überschreiben.
|
||
- Konfiguration **vor** dem Restart prüfen: Handler-Kette Check → Restart (`listen`/`notify`), `meta: flush_handlers` vor `service: started`.
|
||
Bei Fehler bleibt der laufende Dienst unberührt.
|
||
- Jede Rolle hat einen **Smoke-Test** (`verify.yml`, Tag `verify`, `check_mode: false`, `changed_when: false`).
|
||
- **Idempotent:** zweiter Lauf `changed=0`. `command`/`shell` nur mit `creates`/`changed_when`.
|
||
- Module mit FQCN (`ansible.builtin.…`, `community.…`). **Task-Namen in der Amtssprache**, als Satz („Paket installieren“).
|
||
- Variablen der Rolle mit Rollenpräfix (`radius_clients`), Defaults in `defaults/main.yml` mit Kommentar je Variable.
|
||
|
||
## 5. SSH-Performance
|
||
- `pipelining=True` (Standard in `templates/ansible/ansible.cfg`): Module laufen per stdin statt Kopie nach `/tmp` – spart je Task
|
||
mehrere SSH-Roundtrips, typisch der größte Einzelgewinn. Voraussetzung: kein `Defaults requiretty` in `sudoers` (aktuelle Distros: Standard).
|
||
- Dazu `ControlMaster=auto` / `ControlPersist=60s`: eine SSH-Verbindung je Host wird wiederverwendet.
|
||
- Bei Fehlern wie „sudo: sorry, you must have a tty“: `requiretty` auf dem Ziel entfernen, nicht `pipelining` abschalten.
|
||
|
||
## 6. Facts
|
||
- `gathering=smart` + Fact-Cache (`jsonfile`, 86400 s) aus `ansible.cfg`. Facts nutzen statt Shell-Abfragen
|
||
(`ansible_facts['distribution_major_version']`), Zugriff immer über `ansible_facts[...]`, nicht über `ansible_*`-Kurzformen.
|
||
- Facts neu sammeln: `ansible-playbook $ANS_PLAYDIR/mini_check.yml -e check_mode=setup`.
|
||
|
||
## 7. Geheimnisse
|
||
- Secret-Store per `community.hashi_vault` (Lookup in `secrets.yml`), Fallback Ansible Vault (`vault_*`-Variablen).
|
||
- Tasks mit Geheimnissen `no_log: true`, Templates mit Geheimnissen `diff: false`. Nicht entfernen.
|
||
- Testbetrieb ohne Secret-Store: `-e <rolle>_secrets_source=vars -e @/pfad/außerhalb/testsecrets.yml`.
|
||
|
||
## 8. Tags
|
||
`install`, `config`, `verify`; Plattform-Check und Secrets `always`.
|
||
|
||
## 9. Kommentare & Stil
|
||
- Deaktivierte, absichtlich behaltene Blöcke mit `#-#` markieren.
|
||
- YAML: 2 Leerzeichen, `---` am Anfang, `true`/`false` statt `yes`/`no`, Strings mit Jinja in Anführungszeichen.
|
||
- Prüfen vor Abgabe: `ansible-lint`, `yamllint`, `ansible-playbook --syntax-check`, `--check --diff`, Lauf gegen lokalen Testcontainer, Idempotenz (`rules/testing.md`).
|
||
|
||
## 10. Neue Rolle in 5 Schritten
|
||
1. Original-Doku des Dienstes holen (`rules/web_search.md`), Ergebnisse in `knowledge/services/<dienst>.md`.
|
||
2. `cp -r ai/common/templates/ansible/roles/example roles/<dienst>`, `files/example` → `files/<dienst>`, Play aus `playbooks/example.yml`.
|
||
3. Präfix `example_` → `<dienst>_`, Header ausfüllen.
|
||
4. Lokal testen (Container), Idempotenz prüfen.
|
||
5. Knowledge/`context.md` aktualisieren.
|
||
|
||
## Änderungsprotokoll
|
||
- 07.10.2026 – angelegt, verallgemeinert aus infra-devices/ansible.
|
||
- 08.10.2026 – § 5 SSH-Performance (pipelining, ControlPersist) als Vorgabe – Wunsch des Bedieners.
|
||
- 23.10.2026 – Mandantenbezug entfernt (Einzelprojekt).
|