Physical Address
304 North Cardinal St.
Dorchester Center, MA 02124
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.
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.
[Control Node] ─────> [Managed Node 1]
│
├─────────────> [Managed Node 2]
│
└─────────────> [Managed Node 3]
Control Node: Wo Ansible installiert ist
Managed Nodes: Die Systeme, die du verwaltest
Feature | Ansible | Puppet | Chef |
---|---|---|---|
Agentless | ✅ | ❌ | ❌ |
Einfache Syntax | ✅ | ⚠️ | ⚠️ |
Lernkurve | Flach | Steil | Steil |
SSH-basiert | ✅ | ❌ | ❌ |
[Ansible-Struktur]
│
├── [Inventory] (Wo?)
│ └── Liste der Managed Nodes
│
├── [Playbooks] (Was?)
│ └── Automation-Rezepte
│
└── [Module] (Wie?)
└── Die Werkzeuge
⚠️ WICHTIG ZU WISSEN:
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.
Bevor wir mit Ansible loslegen, müssen wir sicherstellen, dass unser System alle Voraussetzungen erfüllt.
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
# Paketquellen aktualisieren
sudo apt update
# System upgraden
sudo apt upgrade -y
# 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
# 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
# Key generieren
ssh-keygen -t ed25519 -C "ansible"
[SSH-Key erstellen]
├── Speicherort bestätigen (Enter)
├── Passwort eingeben (optional)
└── Key wird generiert
# Key kopieren
ssh-copy-id benutzer@zielserver
⚠️ WICHTIGE HINWEISE:
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.
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
# Verzeichnisstruktur erstellen
mkdir -p ansible-projekt/{inventory,group_vars,host_vars,playbooks}
cd ansible-projekt
# ansible.cfg
[defaults]
inventory = ./inventory/staging
remote_user = dein_benutzer
host_key_checking = False
# 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
# Alle Hosts pingen
ansible all -m ping
# Ausgabe sollte so aussehen:
webserver1 | SUCCESS => {
"changed": false,
"ping": "pong"
}
# Details über die Systeme erhalten
ansible all -m setup | grep ansible_distribution
# Zeigt Betriebssystem-Details
⚠️ WICHTIGE HINWEISE:
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]
│
├── Name (Was macht es?)
├── Hosts (Wo läuft es?)
├── Become (Root-Rechte?)
└── Tasks (Was sind die Schritte?)
└── Module (Wie wird's gemacht?)
# Im Projekt-Verzeichnis
cd playbooks
nano webserver.yml
---
- 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
[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
# Prüft, ob das Playbook valide ist
ansible-playbook webserver.yml --syntax-check
# Zeigt, was passieren würde
ansible-playbook webserver.yml --check
# 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:
Jetzt, wo wir die Grundlagen verstehen, schauen wir uns die erweiterten Funktionen an, die Ansible so mächtig machen.
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]
---
- name: Webserver Setup
hosts: webserver
become: yes
vars:
web_root: "/var/www/html"
server_name: "example.com"
max_clients: 150
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"
- name: Create Users
user:
name: "{{ item }}"
state: present
loop:
- john
- jane
- bob
- 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:
Lass uns die gelernten Konzepte in praktischen Beispielen zusammenführen. Wir erstellen ein komplettes Playbook für einen LAMP-Stack (Linux, Apache, MySQL, PHP).
---
- 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
<?php
phpinfo();
?>
<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>
---
- 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 }}"
---
- 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
[Problem-Kategorien]
│
├── [Verbindungsprobleme]
├── [Berechtigungsfehler]
├── [YAML-Syntax]
└── [Modul-Fehler]
# 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
# 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
# Verschiedene Debug-Level
ansible-playbook playbook.yml -v # Detail
ansible-playbook playbook.yml -vv # Mehr Details
ansible-playbook playbook.yml -vvv # Maximale Details
- name: Debug Task
debug:
var: variable_name
msg: "Debugging Information"
verbosity: 2 # Nur bei -vv oder höher
ansible-projekt/
├── ansible.cfg
├── inventory/
│ ├── production/
│ │ ├── hosts
│ │ ├── group_vars/
│ │ └── host_vars/
│ └── staging/
├── roles/
│ ├── common/
│ ├── webserver/
│ └── database/
├── playbooks/
└── README.md
# group_vars/all.yml - Globale Variablen
---
global_var: "wert"
# group_vars/webserver.yml - Gruppen-spezifisch
---
apache_port: 80
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
- name: Geschützter Task
vars_files:
- vault/secrets.yml
tasks:
- name: Setup Database
mysql_user:
name: "{{ db_user }}"
password: "{{ db_password }}"
# 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-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
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.
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
⚠️ Lernziele:
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.