Stell dir vor, du müsstest 100 Server manuell konfigurieren – ein zeitraubender und fehleranfälliger Prozess. Ansible ist wie ein zuverlässiger Assistent, der diese Aufgaben automatisch und zuverlässig für dich erledigt. In diesem Guide lernst du Schritt für Schritt, wie du Ansible einrichtest und effektiv nutzt.
Was ist Ansible?
Ansible ist eine Open-Source-Software zur Automatisierung der Konfiguration und Verwaltung von IT-Infrastruktur und -Anwendungen. Dieser Kurs vermittelt Ihnen die wichtigsten Kenntnisse zu diesem leistungsfähigen Tool.
Wie Ansible arbeitet
[Control Node] ─────> [Managed Node 1]
│
├─────────────> [Managed Node 2]
│
└─────────────> [Managed Node 3]
Control Node: Wo Ansible installiert ist
Managed Nodes: Die Systeme, die du verwaltest
Ansible vs. andere Tools
Feature | Ansible | Puppet | Chef |
---|---|---|---|
Agentless | ✅ | ❌ | ❌ |
Einfache Syntax | ✅ | ⚠️ | ⚠️ |
Lernkurve | Flach | Steil | Steil |
SSH-basiert | ✅ | ❌ | ❌ |
Grundlegende Konzepte
[Ansible-Struktur]
│
├── [Inventory] (Wo?)
│ └── Liste der Managed Nodes
│
├── [Playbooks] (Was?)
│ └── Automation-Rezepte
│
└── [Module] (Wie?)
└── Die Werkzeuge
⚠️ WICHTIG ZU WISSEN:
- Ansible ist agentlos (keine Installation auf Zielservern nötig)
- Verwendet SSH für die Verbindung
- Arbeitet idempotent (wiederholbar, ohne Nebenwirkungen)
- Verwendet YAML für die Konfiguration
Voraussetzungen und Installation
Hinweis: In diesem Artikel verwenden wir Ubuntu als Beispiel-Distribution. Die grundlegenden Konzepte sind auf allen Linux-Systemen gleich, aber die Installation von Paketen und einige Konfigurationspfade können sich je nach Distribution unterscheiden. Wenn du eine andere Distribution verwendest, konsultiere bitte die entsprechende Dokumentation für die spezifischen Installationsbefehle und Pfade.
Was brauchen wir?
Bevor wir mit Ansible loslegen, müssen wir sicherstellen, dass unser System alle Voraussetzungen erfüllt.
Systemanforderungen
Für den Control Node (dein Ubuntu-System):
[Control Node]
├── Ubuntu 24.04 LTS
├── Python 3.x
├── SSH-Client
└── Internetverbindung
Für die Managed Nodes (Zielserver):
[Managed Nodes]
├── SSH-Server
├── Python 3.x
└── Sudo-Rechte
Installation
System aktualisieren:
# Paketquellen aktualisieren
sudo apt update
# System upgraden
sudo apt upgrade -y
Ansible installieren:
# Benötigte Pakete installieren
sudo apt install software-properties-common
# Ansible Repository hinzufügen
sudo add-apt-repository --yes --update ppa:ansible/ansible
# Ansible installieren
sudo apt install ansible
Installation überprüfen:
# Version prüfen
ansible --version
Du solltest eine Ausgabe wie diese sehen:
ansible [core 2.14.x]
config file = /etc/ansible/ansible.cfg
configured module search path = [...]
ansible python module location = [...]
ansible collection location = [...]
executable location = /usr/bin/ansible
python version = 3.10.x
SSH-Konfiguration
SSH-Key erstellen:
# Key generieren
ssh-keygen -t ed25519 -C "ansible"
[SSH-Key erstellen]
├── Speicherort bestätigen (Enter)
├── Passwort eingeben (optional)
└── Key wird generiert
Key auf Zielserver kopieren:
# Key kopieren
ssh-copy-id benutzer@zielserver
⚠️ WICHTIGE HINWEISE:
- Verwende starke Passwörter
- Sichere deine SSH-Keys
- Notiere dir die Zugangsdaten
- Prüfe die Verbindung
Ansible-Struktur
Wie ist Ansible aufgebaut?
Bevor wir mit den ersten Befehlen starten, lass uns verstehen, wie Ansible strukturiert ist. Denk an Ansible wie an ein Kochbuch: Das Inventory sind deine Zutaten, die Playbooks deine Rezepte, und die Module sind deine Küchenwerkzeuge.
Die Grundstruktur eines Ansible-Projekts
ansible-projekt/
├── ansible.cfg # Konfigurationsdatei
├── inventory/ # Verzeichnis für Inventare
│ ├── production # Produktionsserver
│ └── staging # Testserver
├── group_vars/ # Gruppenvariablen
│ └── all.yml # Gilt für alle Gruppen
├── host_vars/ # Host-spezifische Variablen
│ └── webserver1.yml # Gilt für einzelnen Host
└── playbooks/ # Deine Automation-Rezepte
└── webserver.yml # Beispiel-Playbook
Grundstruktur und Erste Schritte
1. Projekt-Verzeichnis anlegen:
# Verzeichnisstruktur erstellen
mkdir -p ansible-projekt/{inventory,group_vars,host_vars,playbooks}
cd ansible-projekt
2. Ansible-Konfiguration erstellen:
# ansible.cfg
[defaults]
inventory = ./inventory/staging
remote_user = dein_benutzer
host_key_checking = False
3. Erstes Inventory erstellen:
# inventory/staging
[webserver]
webserver1 ansible_host=192.168.1.10
webserver2 ansible_host=192.168.1.11
[database]
db1 ansible_host=192.168.1.20
[all:vars]
ansible_python_interpreter=/usr/bin/python3
Erste Schritte
1. Verbindung testen:
# Alle Hosts pingen
ansible all -m ping
# Ausgabe sollte so aussehen:
webserver1 | SUCCESS => {
"changed": false,
"ping": "pong"
}
2. System-Informationen abrufen:
# Details über die Systeme erhalten
ansible all -m setup | grep ansible_distribution
# Zeigt Betriebssystem-Details
⚠️ WICHTIGE HINWEISE:
- Stelle sicher, dass SSH-Zugriff auf alle Hosts möglich ist
- Python muss auf allen Zielservern installiert sein
- Rechte müssen korrekt gesetzt sein
- Firewall-Regeln müssen SSH erlauben
Dein erstes Playbook erstellen
Playbooks – Die Automation-Rezepte
Ein Playbook ist wie ein Rezept – es beschreibt Schritt für Schritt, was auf den Zielservern passieren soll. Lass uns ein einfaches Playbook erstellen, das einen Webserver installiert.
Playbook-Struktur
[Playbook]
│
├── Name (Was macht es?)
├── Hosts (Wo läuft es?)
├── Become (Root-Rechte?)
└── Tasks (Was sind die Schritte?)
└── Module (Wie wird's gemacht?)
Erstes Playbook erstellen
1. Datei anlegen:
# Im Projekt-Verzeichnis
cd playbooks
nano webserver.yml
2. Playbook schreiben:
---
- name: Apache install and start
hosts: webserver
become: yes
tasks:
- name: Install Apache
apt:
name: apache2
state: latest
update_cache: yes
- name: Ensure Apache is running
service:
name: apache2
state: started
enabled: yes
- name: Allow Apache through firewall
ufw:
rule: allow
port: 80
proto: tcp
Playbook verstehen
Was macht jeder Teil?
[name: Apache install and start]
└── Beschreibender Name des Playbooks
[hosts: webserver]
└── Läuft auf Hosts in der Gruppe "webserver"
[become: yes]
└── Führt Befehle mit Root-Rechten aus
[tasks:]
├── Install Apache
│ └── Installiert das Paket
├── Ensure Apache is running
│ └── Startet den Dienst
└── Allow Apache through firewall
└── Öffnet Port 80
Playbook ausführen
1. Syntax prüfen:
# Prüft, ob das Playbook valide ist
ansible-playbook webserver.yml --syntax-check
2. Testlauf (Dry-Run):
# Zeigt, was passieren würde
ansible-playbook webserver.yml --check
3. Tatsächliche Ausführung:
# Führt das Playbook aus
ansible-playbook webserver.yml
Die Ausgabe sollte etwa so aussehen:
PLAY [Apache install and start] ************
TASK [Install Apache] *********************
changed: [webserver1]
changed: [webserver2]
TASK [Ensure Apache is running] ***********
ok: [webserver1]
ok: [webserver2]
TASK [Allow Apache through firewall] ******
changed: [webserver1]
changed: [webserver2]
PLAY RECAP *******************************
webserver1 : ok=3 changed=2 unreachable=0 failed=0
webserver2 : ok=3 changed=2 unreachable=0 failed=0
⚠️ WICHTIGE HINWEISE:
- Playbooks sind idempotent (mehrfache Ausführung ist sicher)
- Reihenfolge der Tasks ist wichtig
- Einrückung in YAML muss stimmen
- Fehler werden sofort angezeigt

Erweiterte Playbook-Funktionen
Fortgeschrittene Ansible-Funktionen
Jetzt, wo wir die Grundlagen verstehen, schauen wir uns die erweiterten Funktionen an, die Ansible so mächtig machen.
Handlers
Handler sind spezielle Tasks, die nur ausgeführt werden, wenn sie durch eine Änderung ausgelöst werden:
---
- name: Apache Configuration
hosts: webserver
become: yes
tasks:
- name: Copy Apache config
template:
src: apache.conf.j2
dest: /etc/apache2/apache2.conf
mode: '0644'
notify: Restart Apache
handlers:
- name: Restart Apache
service:
name: apache2
state: restarted
[Task] ──> [Änderung?] ──> [Handler]
│
└── Nein ─────> [Weiter]
Variablen und Templates
1. Variablen definieren:
---
- name: Webserver Setup
hosts: webserver
become: yes
vars:
web_root: "/var/www/html"
server_name: "example.com"
max_clients: 150
2. Jinja2 Template (apache.conf.j2):
ServerName {{ server_name }}
DocumentRoot {{ web_root }}
MaxClients {{ max_clients }}
Bedingungen (Conditionals)
---
- name: Conditional Tasks
hosts: all
tasks:
- name: Install Apache on Ubuntu
apt:
name: apache2
state: present
when: ansible_distribution == "Ubuntu"
- name: Install Apache on CentOS
yum:
name: httpd
state: present
when: ansible_distribution == "CentOS"
Loops
1. Einfache Schleife:
- name: Create Users
user:
name: "{{ item }}"
state: present
loop:
- john
- jane
- bob
2. Komplexere Schleife:
- name: Create Users with Details
user:
name: "{{ item.name }}"
groups: "{{ item.groups }}"
shell: "{{ item.shell }}"
loop:
- { name: 'john', groups: 'admin', shell: '/bin/bash' }
- { name: 'jane', groups: 'dev', shell: '/bin/zsh' }
⚠️ WICHTIGE HINWEISE:
- Handler werden nur einmal am Ende ausgeführt
- Variablen sind Case-sensitive
- Bedingungen können verschachtelt werden
- Loops erhöhen die Ausführungszeit
Praktische Beispiele
Reale Anwendungsfälle
Lass uns die gelernten Konzepte in praktischen Beispielen zusammenführen. Wir erstellen ein komplettes Playbook für einen LAMP-Stack (Linux, Apache, MySQL, PHP).
LAMP-Stack Installation
---
- name: LAMP Stack Setup
hosts: webserver
become: yes
vars:
mysql_root_password: "secure_password"
app_user: "webadmin"
app_group: "www-data"
web_root: "/var/www/html"
tasks:
# Update System
- name: Update apt cache
apt:
update_cache: yes
cache_valid_time: 3600
# Install Packages
- name: Install LAMP packages
apt:
name: "{{ item }}"
state: present
loop:
- apache2
- mysql-server
- php
- php-mysql
- python3-pymysql
notify: Restart Apache
# Apache Configuration
- name: Create web root
file:
path: "{{ web_root }}"
state: directory
owner: "{{ app_user }}"
group: "{{ app_group }}"
mode: '0755'
# MySQL Secure Installation
- name: Set MySQL root password
mysql_user:
name: root
password: "{{ mysql_root_password }}"
login_unix_socket: /var/run/mysqld/mysqld.sock
state: present
# PHP Test File
- name: Create PHP info page
template:
src: info.php.j2
dest: "{{ web_root }}/info.php"
mode: '0644'
notify: Restart Apache
handlers:
- name: Restart Apache
service:
name: apache2
state: restarted
Templates und Konfigurationen
1. PHP Info Template (info.php.j2):
<?php
phpinfo();
?>
2. Apache VHost Template (vhost.conf.j2):
<VirtualHost *:80>
ServerAdmin webmaster@{{ server_name }}
DocumentRoot {{ web_root }}
ServerName {{ server_name }}
<Directory {{ web_root }}>
Options Indexes FollowSymLinks
AllowOverride All
Require all granted
</Directory>
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>
Benutzer und Berechtigungen
---
- name: User Management
hosts: webserver
become: yes
vars:
users:
- name: john
groups: ['admin', 'www-data']
shell: /bin/bash
- name: jane
groups: ['dev', 'www-data']
shell: /bin/zsh
tasks:
- name: Create user groups
group:
name: "{{ item }}"
state: present
loop:
- admin
- dev
- www-data
- name: Create users
user:
name: "{{ item.name }}"
groups: "{{ item.groups | join(',') }}"
shell: "{{ item.shell }}"
state: present
loop: "{{ users }}"
- name: Set up SSH keys
authorized_key:
user: "{{ item.name }}"
key: "{{ lookup('file', 'keys/' + item.name + '.pub') }}"
loop: "{{ users }}"
Fehlerbehandlung und Debugging
---
- name: Error Handling Example
hosts: webserver
become: yes
tasks:
- name: Check Apache status
command: systemctl status apache2
register: apache_status
ignore_errors: yes
- name: Debug Apache status
debug:
var: apache_status.stdout_lines
when: apache_status.rc == 0
- name: Handle Apache failure
block:
- name: Restart Apache
service:
name: apache2
state: restarted
rescue:
- name: Log failure
debug:
msg: "Apache restart failed!"
always:
- name: Check final status
command: systemctl status apache2
⚠️ BEST PRACTICES:
[Playbook Organisation]
├── Variablen auslagern
├── Templates verwenden
├── Fehlerbehandlung einbauen
└── Idempotenz sicherstellen
[Sicherheit]
├── Sensitive Daten verschlüsseln
├── Berechtigungen prüfen
└── Logging aktivieren
Troubleshooting
Häufige Probleme und Lösungen
[Problem-Kategorien]
│
├── [Verbindungsprobleme]
├── [Berechtigungsfehler]
├── [YAML-Syntax]
└── [Modul-Fehler]
1. Verbindungsprobleme:
# Problem: SSH-Verbindung fehlgeschlagen
ansible webserver -m ping
# Fehler: "UNREACHABLE!"
# Lösung: Verbindung testen
ssh benutzer@zielserver
# Debug-Modus aktivieren
ansible webserver -m ping -vvv
2. YAML-Syntax überprüfen:
# Häufige Fehler:
- name: Falsches YAML
apt:
name: apache2 # Falsche Einrückung!
state: present
# Korrektes YAML:
- name: Korrektes YAML
apt:
name: apache2 # Korrekte Einrückung
state: present
Debugging-Techniken
1. Verbose-Modi:
# Verschiedene Debug-Level
ansible-playbook playbook.yml -v # Detail
ansible-playbook playbook.yml -vv # Mehr Details
ansible-playbook playbook.yml -vvv # Maximale Details
2. Debug-Module verwenden:
- name: Debug Task
debug:
var: variable_name
msg: "Debugging Information"
verbosity: 2 # Nur bei -vv oder höher
Best Practices
1. Projektstruktur:
ansible-projekt/
├── ansible.cfg
├── inventory/
│ ├── production/
│ │ ├── hosts
│ │ ├── group_vars/
│ │ └── host_vars/
│ └── staging/
├── roles/
│ ├── common/
│ ├── webserver/
│ └── database/
├── playbooks/
└── README.md
2. Variablen-Management:
# group_vars/all.yml - Globale Variablen
---
global_var: "wert"
# group_vars/webserver.yml - Gruppen-spezifisch
---
apache_port: 80
3. Rollen-Struktur:
roles/webserver/
├── defaults/
│ └── main.yml # Standard-Variablen
├── handlers/
│ └── main.yml # Handler-Definitionen
├── tasks/
│ └── main.yml # Hauptaufgaben
├── templates/
│ └── vhost.conf.j2
└── vars/
└── main.yml # Rollen-Variablen
Sicherheits-Best-Practices
1. Sensitive Daten verschlüsseln
- name: Geschützter Task
vars_files:
- vault/secrets.yml
tasks:
- name: Setup Database
mysql_user:
name: "{{ db_user }}"
password: "{{ db_password }}"
2. Vault verwenden:
# Verschlüsselte Datei erstellen
ansible-vault create secrets.yml
# Verschlüsselte Datei bearbeiten
ansible-vault edit secrets.yml
# Playbook mit Vault ausführen
ansible-playbook site.yml --ask-vault-pass
Performance-Optimierung
[Performance-Tipps]
├── Parallele Ausführung
│ └── fork: 10
├── Pipelining aktivieren
│ └── pipelining = True
└── Fact-Gathering begrenzen
└── gather_facts: no
⚠️ WICHTIGE HINWEIS
1. Dokumentation
[Dokumentiere]
├── Playbooks
├── Variablen
├── Abhängigkeiten
└── Besonderheiten
2. Testing
[Test-Strategie]
├── Syntax-Check
├── --check (Dry-Run)
├── Staging-Umgebung
└── Idempotenz-Test
3. Versionskontrolle
[Git-Struktur]
├── .gitignore
├── Branches
└── Tags für Releases
Übung
Webserver-Deployment mit Ansible
Szenario: Du bist DevOps-Engineer in einem kleinen Unternehmen. Deine Aufgabe ist es, einen Webserver für das Entwicklungsteam einzurichten. Der Server soll Apache, PHP und eine einfache Testseite enthalten.
Aufgabe
- Erstelle ein Playbook, das:
- Apache und PHP installiert
- Eine individuelle index.php erstellt
- Die Apache-Konfiguration anpasst
- Den Dienst startet und aktiviert
- Verwende Variablen für:
- Document Root
- Server Name
- PHP-Version
- Implementiere einen Handler für Apache-Neustarts
- Füge Basic Error Handling hinzu
Mögliche Lösung
1. Verzeichnisstruktur erstellen:
mkdir -p webserver-uebung/{playbooks,templates}
cd webserver-uebung
2. Inventory erstellen (inventory/hosts):
[webserver]
testserver ansible_host=192.168.1.10
3. Template erstellen (templates/index.php.j2):
<?php
echo "<h1>Willkommen auf {{ server_name }}</h1>";
echo "<p>PHP Version: " . phpversion() . "</p>";
echo "<p>Server Zeit: " . date('Y-m-d H:i:s') . "</p>";
?>
4. Playbook erstellen (playbooks/webserver.yml):
---
- name: Webserver Setup
hosts: webserver
become: yes
vars:
server_name: "dev.example.com"
doc_root: "/var/www/html"
php_version: "8.1"
tasks:
- name: Update apt cache
apt:
update_cache: yes
register: apt_update
ignore_errors: yes
- name: Install required packages
apt:
name:
- apache2
- "php{{ php_version }}"
state: present
notify: Restart Apache
- name: Create custom index.php
template:
src: templates/index.php.j2
dest: "{{ doc_root }}/index.php"
mode: '0644'
notify: Restart Apache
- name: Ensure Apache is running
service:
name: apache2
state: started
enabled: yes
handlers:
- name: Restart Apache
service:
name: apache2
state: restarted
5. Ausführen und Testen:
# Syntax prüfen
ansible-playbook playbooks/webserver.yml --syntax-check
# Testlauf
ansible-playbook playbooks/webserver.yml --check
# Ausführen
ansible-playbook playbooks/webserver.yml
Erwartetes Ergebnis
- Apache und PHP sind installiert
- Eine personalisierte index.php ist verfügbar
- Apache läuft und startet automatisch
- Die Webseite ist über den Browser erreichbar
⚠️ Lernziele:
- Verwendung von Templates
- Arbeit mit Variablen
- Handler implementieren
- Fehlerbehandlung
- Idempotenz verstehen
Wichtige Ressourcen
Offizielle Dokumentation und Hilfen
- Ansible Dokumentation: https://docs.ansible.com/
- Ansible Galaxy (Rollen-Repository): https://galaxy.ansible.com/
- Ansible GitHub: https://github.com/ansible/ansible
- Ansible Module Index: https://docs.ansible.com/ansible/latest/collections/index_module.html
Nützliche Tools
- Ansible Lint: https://ansible-lint.readthedocs.io/
- Molecule (Testing Framework): https://molecule.readthedocs.io/
- YAML Validator: https://www.yamllint.com/
- Ansible Vault: https://docs.ansible.com/ansible/latest/vault_guide/
Community & Support
- Ansible Reddit: https://www.reddit.com/r/ansible/
- Stack Overflow Ansible: https://stackoverflow.com/questions/tagged/ansible
- Ansible Mailing List: https://groups.google.com/g/ansible-project
- Ansible Discord: https://discord.com/invite/ansible
Lern-Ressourcen
- Ansible Workshop: https://ansible.github.io/workshops/
- Ansible Examples: https://github.com/ansible/ansible-examples
- Ansible Best Practices: https://docs.ansible.com/ansible/latest/user_guide/playbooks_best_practices.html
Fazit
Ansible hat sich in den letzten Jahren zu einem der wichtigsten Werkzeuge für IT-Automation entwickelt, und das aus gutem Grund. Seine agentlose Architektur, die lesbare YAML-Syntax und die breite Community-Unterstützung machen es zu einer ausgezeichneten Wahl für Einsteiger und Profis gleichermaßen.
In diesem kleinem Kurs haben wir gesehen, wie Ansible die Komplexität der Systemadministration reduziert und wiederholbare, zuverlässige Deployments ermöglicht. Von der einfachen Installation über die Erstellung von Playbooks bis hin zu fortgeschrittenen Konzepten wie Rollen und Templates – Ansible bietet für jede Automatisierungsaufgabe die passenden Werkzeuge.
Besonders wertvoll ist die Idempotenz von Ansible, die sicherstellt, dass unsere Systeme konsistent bleiben, egal wie oft wir unsere Playbooks ausführen. Dies, kombiniert mit der umfangreichen Modulbibliothek und der aktiven Community, macht Ansible zu einer zukunftssicheren Investition in die IT-Automation.
Die wahre Stärke von Ansible liegt jedoch in seiner Flexibilität:
Ob kleine Homelab-Umgebungen oder große Unternehmensinfrastrukturen, Ansible skaliert mit deinen Bedürfnissen und wächst mit deinen Anforderungen. Mit den in diesem Guide erlernten Grundlagen bist du bestens gerüstet, um deine eigenen Automatisierungsprojekte in Angriff zu nehmen und die Effizienz deiner IT-Infrastruktur zu steigern.