Anpassung für vault hinzugefügt
This commit is contained in:
@@ -0,0 +1,356 @@
|
||||
# Ansible — Syntax & Variablen-Handout
|
||||
|
||||
Kompakte Referenz zu YAML-Syntax, Ad-hoc-Befehlen, Jinja2, Facts, Variablen-Auflösung, Ansible Vault, FQCN und ansible.cfg.
|
||||
|
||||
---
|
||||
|
||||
## 1. YAML-Grundsyntax
|
||||
|
||||
| Element | Syntax | Beispiel |
|
||||
|--------------------|-----------------|--------------------------|
|
||||
| Schlüssel-Wert | `key: wert` | `name: webserver` |
|
||||
| Liste | `- eintrag` | `- nginx` |
|
||||
| Verschachtelung | Einrückung | 2 Leerzeichen (KEINE Tabs) |
|
||||
| Kommentar | `# text` | `# Dies ist ein Kommentar` |
|
||||
| Zeichenkette | mit/ohne Quotes | `name: "Mein Server"` |
|
||||
|
||||
Einrückung mit 2 Leerzeichen (niemals Tabs!):
|
||||
|
||||
```yaml
|
||||
user:
|
||||
name: admin
|
||||
shell: /bin/bash
|
||||
groups:
|
||||
- sudo
|
||||
- docker
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 2. Ad-hoc-Befehle (ohne Playbook)
|
||||
|
||||
```bash
|
||||
ansible <hosts> -m <modul> -a "<argumente>"
|
||||
```
|
||||
|
||||
Beispiele:
|
||||
|
||||
```bash
|
||||
# Erreichbarkeit testen
|
||||
ansible all -m ping
|
||||
|
||||
# Facts anzeigen
|
||||
ansible webserver -m setup
|
||||
|
||||
# Paket installieren (mit become/-b für Root-Rechte)
|
||||
ansible webserver -b -m apt -a "name=nginx state=present"
|
||||
|
||||
# Dienst neu starten (mit become/-b)
|
||||
ansible webserver -b -m service -a "name=nginx state=restarted"
|
||||
```
|
||||
|
||||
Wichtige Optionen:
|
||||
|
||||
| Option | Bedeutung |
|
||||
|--------|----------------------|
|
||||
| `-m` | Modul wählen |
|
||||
| `-a` | Argumente übergeben |
|
||||
| `-i` | Inventory angeben |
|
||||
| `-b` | become (sudo) |
|
||||
| `-u` | Benutzer |
|
||||
|
||||
**Lokal gegen localhost:**
|
||||
|
||||
`localhost` ist kein echter Host im Netzwerk. Um direkt auf dem eigenen Rechner
|
||||
zu laufen (ohne SSH), nutzt man im Playbook:
|
||||
|
||||
```yaml
|
||||
- hosts: localhost # Hostname: localhost
|
||||
connection: local # Connection-Typ: local (nicht "localhost"!)
|
||||
gather_facts: true
|
||||
become: true # sudo für z.B. Paket-Installation
|
||||
```
|
||||
|
||||
> `hosts: localhost` (Host) und `connection: local` (Typ) sind zwei verschiedene
|
||||
> Angaben — `localhost` ist der Hostname, `local` der Connection-Typ.
|
||||
|
||||
---
|
||||
|
||||
## 3. Jinja2 — Variablen auflösen
|
||||
|
||||
Ansible nutzt die Template-Engine **Jinja2**. Variablen werden in doppelte
|
||||
geschweifte Klammern gesetzt:
|
||||
|
||||
```yaml
|
||||
# Wert einsetzen
|
||||
message: "Hallo {{ benutzer }}"
|
||||
path: "/home/{{ benutzer }}/.config"
|
||||
|
||||
# Verschachtelte Variablen
|
||||
db_host: "{{ hostvars['db'].ansible_host }}"
|
||||
```
|
||||
|
||||
### Filter
|
||||
|
||||
```yaml
|
||||
name: "{{ name | upper }}" # -> GROSSSCHREIBUNG
|
||||
port: "{{ port | default(80) }}" # Fallback, wenn Variable leer
|
||||
anzahl: "{{ liste | length }}" # Anzahl der Elemente
|
||||
ip: "{{ ansible_host | ipaddr }}" # IP-Adresse validieren
|
||||
```
|
||||
|
||||
### Template-Dateien (.j2)
|
||||
|
||||
Dateien mit Endung `.j2` werden vom Modul `template` gerendert:
|
||||
|
||||
```jinja
|
||||
# nginx.conf.j2
|
||||
server {
|
||||
listen {{ nginx_port }};
|
||||
server_name {{ domain }};
|
||||
root {{ web_root }};
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4. Gather Facts (Systeminformationen)
|
||||
|
||||
Ansible sammelt automatisch **Facts** (Systeminformationen) über jeden Host —
|
||||
ü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:
|
||||
|
||||
| Fact | Bedeutung |
|
||||
|-----------------------------------|-------------------------------|
|
||||
| `ansible_facts['os_family']` | OS-Familie (Debian, RedHat) |
|
||||
| `ansible_facts['distribution']` | z.B. Ubuntu, CentOS, Debian |
|
||||
| `ansible_facts['distribution_version']` | Version (z.B. 22.04) |
|
||||
| `ansible_facts['hostname']` | Hostname des Systems |
|
||||
| `ansible_facts['default_ipv4']['address']` | IP-Adresse |
|
||||
| `ansible_facts['architecture']` | CPU-Architektur (x86_64) |
|
||||
| `ansible_facts['memtotal_mb']` | RAM in MB |
|
||||
| `ansible_facts['processor_vcpus']`| Anzahl CPU-Kerne |
|
||||
|
||||
Zugriff im Playbook:
|
||||
|
||||
```yaml
|
||||
- name: OS anzeigen
|
||||
ansible.builtin.debug:
|
||||
msg: "{{ ansible_facts['distribution'] }} {{ ansible_facts['distribution_version'] }}"
|
||||
```
|
||||
|
||||
Eigene Facts (Custom Facts) setzen:
|
||||
|
||||
```bash
|
||||
# Datei anlegen (INI-Format):
|
||||
# /etc/ansible/facts.d/app.fact
|
||||
# Inhalt:
|
||||
# [app]
|
||||
# version=1.2.3
|
||||
# Abruf (der Name des .fact-Files wird zum Unter-Key):
|
||||
# {{ ansible_facts['ansible_local']['app']['version'] }}
|
||||
```
|
||||
|
||||
Facts deaktivieren (Performance):
|
||||
|
||||
```yaml
|
||||
gather_facts: false
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5. Wo Variablen definiert werden
|
||||
|
||||
| Quelle | Datei / Ort | Beispiel |
|
||||
|------------|------------------------------------|---------------------------------|
|
||||
| Inventory | `host_vars/`, `group_vars/` | `group_vars/webserver.yml` |
|
||||
| Playbook | `vars:` / `vars_files:` | `vars: { port: 8080 }` |
|
||||
| Rolle | `roles/<rolle>/vars/` + `defaults/`| `vars/main.yml` |
|
||||
| Facts | automatisch gesammelt | `ansible_facts['os_family']` |
|
||||
| Laufzeit | `register` / `set_fact` | `register: result` |
|
||||
| CLI | Extra-Variablen | `-e "port=8080"` |
|
||||
|
||||
---
|
||||
|
||||
## 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
|
||||
**höchsten** Priorität (oben = gewinnt):
|
||||
|
||||
1. **Extra-Variablen** (CLI `-e`) — gewinnen immer
|
||||
2. **Task-/Block-Variablen** (`vars:` direkt an der Aufgabe)
|
||||
3. **set_fact / register** (Werte aus der Laufzeit)
|
||||
4. **Rollen-Variablen** (`roles/.../vars/main.yml`)
|
||||
5. **Playbook-Variablen** (`vars:` im Play)
|
||||
6. **host_vars / group_vars** (aus dem Inventory)
|
||||
7. **Rollen-Defaults** (`roles/.../defaults/main.yml`) — verlieren
|
||||
|
||||
> **Faustregel:** Je spezifischer die Quelle, desto höher die Priorität.
|
||||
|
||||
---
|
||||
|
||||
## 8. Module & FQCN
|
||||
|
||||
FQCN = **Fully Qualified Collection Name** — `namespace.collection.modul`.
|
||||
|
||||
```yaml
|
||||
ansible.builtin.apt:
|
||||
name: nginx
|
||||
state: present
|
||||
```
|
||||
|
||||
| FQCN | Zweck |
|
||||
|-----------------------------------|---------------------------|
|
||||
| `ansible.builtin.copy` | Datei kopieren |
|
||||
| `ansible.builtin.apt` | Paket installieren (Debian) |
|
||||
| `ansible.builtin.service` | Dienst verwalten |
|
||||
| `ansible.builtin.template` | `.j2`-Template rendern |
|
||||
| `ansible.posix.firewalld` | Firewall konfigurieren |
|
||||
| `community.general.git_config` | Git-Einstellungen |
|
||||
|
||||
---
|
||||
|
||||
## 9. 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
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 10. Vollständiges Beispiel
|
||||
|
||||
**Playbook** (`deploy.yml`):
|
||||
|
||||
```yaml
|
||||
- name: Webserver ausrollen
|
||||
hosts: webserver
|
||||
become: true
|
||||
vars:
|
||||
nginx_port: 8080 # überschreibt den Rollen-Default
|
||||
roles:
|
||||
- webserver
|
||||
```
|
||||
|
||||
**Rollen-Defaults** (`roles/webserver/defaults/main.yml`) — niedrigste Priorität:
|
||||
|
||||
```yaml
|
||||
nginx_port: 80
|
||||
domain: example.com
|
||||
```
|
||||
|
||||
**Rollen-Tasks** (`roles/webserver/tasks/main.yml`):
|
||||
|
||||
```yaml
|
||||
- name: nginx installieren
|
||||
ansible.builtin.apt:
|
||||
name: nginx
|
||||
state: present
|
||||
|
||||
- name: Konfiguration rendern
|
||||
ansible.builtin.template:
|
||||
src: nginx.conf.j2
|
||||
dest: /etc/nginx/nginx.conf
|
||||
```
|
||||
Reference in New Issue
Block a user