Schritt für Schritt

Ansible: alles automatisch

Kapitel 04 von 164 Min. Lesezeitaktualisiert 17.10.2026

Zehn Container von Hand aktuell zu halten, macht niemand lange. Ansible erledigt das mit einem einzigen Befehl und sorgt dafür, dass alle Container gleich eingerichtet sind.

Was ist Ansible?

Ansible ist ein Open-Source-Werkzeug zur Automatisierung. Man beschreibt in einfachen Textdateien (Playbooks, im YAML-Format), wie ein System aussehen soll: welche Pakete installiert sind, welche Benutzer es gibt, welche Dienste laufen. Ansible verbindet sich per SSH mit allen Containern und sorgt dafür, dass genau dieser Zustand hergestellt wird. Auf den Containern muss nichts installiert sein außer SSH und Python, beides steckt schon in unserer Vorlage.

  • Inventar: die Liste aller Container, gern in Gruppen sortiert.
  • Playbook: eine Abfolge von Aufgaben, z. B. „alle Updates einspielen“.
  • Idempotent: Ein Playbook darf beliebig oft laufen. Ist schon alles richtig, ändert es nichts.

Installation

Ansible läuft auf dem Rechner, von dem aus man verwaltet, dem Control Node. Das kann der eigene Mac oder Linux-Rechner sein, oder ein eigener kleiner Container ansible aus der Vorlage.

# macOS
brew install ansible

# Debian (z. B. im Container „ansible“)
sudo apt install -y ansible

ansible --version

Das Projekt anlegen

vereins-it/
├── ansible.cfg
├── inventory.ini
├── base.yml        Grundeinrichtung aller Container
└── update.yml      Updates für alle

Den Ordner lege ich in ein Git-Repository. Dann ist jede Änderung an der Infrastruktur nachvollziehbar, und ein Nachfolger findet alles an einem Ort.

# ansible.cfg
[defaults]
inventory = inventory.ini
remote_user = admin
host_key_checking = True
interpreter_python = auto_silent
# inventory.ini
[infrastruktur]
proxy       ansible_host=192.168.178.30
login       ansible_host=192.168.178.31
status      ansible_host=192.168.178.32

[anwendungen]
paperless   ansible_host=192.168.178.40
medien      ansible_host=192.168.178.41
mitglieder  ansible_host=192.168.178.42
flows       ansible_host=192.168.178.43
web         ansible_host=192.168.178.44
cloud       ansible_host=192.168.178.45
tresor      ansible_host=192.168.178.46

[verein:children]
infrastruktur
anwendungen

Erster Test: Antworten alle Container?

ansible verein -m ping

Playbook: Updates für alle

# update.yml
- name: Alle Container aktualisieren
  hosts: verein
  become: true
  serial: 1                       # einer nach dem anderen, nie alle gleichzeitig
  tasks:
    - name: Paketlisten holen und alles aktualisieren
      ansible.builtin.apt:
        update_cache: true
        upgrade: dist
        autoremove: true

    - name: Prüfen, ob ein Neustart nötig ist
      ansible.builtin.stat:
        path: /var/run/reboot-required
      register: reboot_needed

    - name: Neu starten, falls nötig
      ansible.builtin.reboot:
      when: reboot_needed.stat.exists
ansible-playbook update.yml --check   # erst nur anzeigen, was passieren würde
ansible-playbook update.yml

Playbook: Grundeinrichtung

Alles, was jeder Container haben soll, steht an einer Stelle. Kommt ein neuer Container dazu, läuft das Playbook einmal über ihn, und er ist auf demselben Stand wie alle anderen.

# base.yml
- name: Grundeinrichtung
  hosts: verein
  become: true
  vars:
    admin_keys:
      - "ssh-ed25519 AAAA... jan@laptop"
  tasks:
    - name: Basispakete
      ansible.builtin.apt:
        name: [sudo, curl, ca-certificates, unattended-upgrades, htop, ncdu]
        state: present
        update_cache: true

    - name: Zeitzone
      community.general.timezone:
        name: Europe/Berlin

    - name: SSH-Schlüssel der Verwalter
      ansible.posix.authorized_key:
        user: admin
        key: "{{ item }}"
      loop: "{{ admin_keys }}"

    - name: SSH nur noch mit Schlüssel
      ansible.builtin.lineinfile:
        path: /etc/ssh/sshd_config.d/10-verein.conf
        create: true
        line: "{{ item }}"
      loop:
        - "PasswordAuthentication no"
        - "PermitRootLogin prohibit-password"
      notify: ssh neu laden

  handlers:
    - name: ssh neu laden
      ansible.builtin.service:
        name: ssh
        state: reloaded

Die Module community.general und ansible.posix sind bei einer normalen Ansible-Installation dabei. Falls nicht: ansible-galaxy collection install community.general ansible.posix.

Der nächste Schritt

Mit der Sammlung community.proxmox kann Ansible auch die Container selbst in Proxmox anlegen, klonen und starten. Dann ist die komplette Infrastruktur vom Container bis zur Anwendung beschrieben und lässt sich auf neuer Hardware in einer Stunde wieder aufbauen. Das ist das Ziel, aber kein Muss für den Anfang: Erst Updates und Grundeinrichtung automatisieren, dann Schritt für Schritt mehr.

Tipp: Vor großen Updates erst Snapshots aller Container in Proxmox anlegen und dann ansible-playbook update.yml laufen lassen. Geht etwas schief, ist jeder einzelne Container in Sekunden zurückgesetzt.

Moin!

Stehst du vor ähnlichen Fragen?

Ob eigener Verein, Homelab oder einfach Neugier: Ich freue mich über Fragen und Erfahrungen.