---
title: "Ansible vs Terraform: Der Vergleich für Einsteiger"
description: "Ein Server kann existieren, ohne Anfragen zu bedienen. Der Vergleich erklärt Terraform und Ansible mit verständlichen Diagrammen und einem vollständigen Beispiel."
author: Aleksei Aleinikov
date: 2026-11-12
lang: de
tags: [ansible, terraform, infrastructure-as-code, configuration-management, devops, automation, aws]
canonical: https://www.alekseialeinikov.com/de/blog/topics/devops/ansible-vs-terraform-vergleich
source: alekseialeinikov.com
---

# Ansible vs Terraform: Der Vergleich für Einsteiger

Die Cloud-Konsole meldet einen laufenden Server. Der Browser zeigt „Verbindung abgelehnt“. Beides kann stimmen: Eine Maschine anzulegen und eine nutzbare Anwendung bereitzustellen sind unterschiedliche Aufgaben.

**Ansible vs Terraform wird an dieser Grenze verständlich.** Terraform ist meist der bessere Ausgangspunkt für Infrastrukturressourcen. Ansible ist meist der bessere Ausgangspunkt für Systemkonfiguration und koordinierte Betriebsaufgaben. Viele Teams nutzen beide; kleinere Systeme kommen häufig mit einem Werkzeug aus. Entscheidend ist, wer welchen Teil der Arbeit übernimmt.

![Ansible vs Terraform: Ein Miniaturhaus verbindet einen violetten Rohbau mit einer warm beleuchteten, ausgestatteten Einrichtung.](https://www.alekseialeinikov.com/blog/ansible-vs-terraform.webp)

> [!NOTE]
> Grundlage sind die offiziellen Dokumentationen von HashiCorp und Ansible, geprüft am 12. November 2026. Das herunterladbare Beispiel ist eine dokumentationsbasierte Anleitung, kein Cloud-Benchmark und kein gegen ein echtes AWS-Konto verifizierter Deployment-Test. Voraussetzungen und Grenzen stehen ausdrücklich im Text.

## Ansible vs Terraform: die schnelle Entscheidung

| Deine unmittelbare Aufgabe | Sinnvoller Einstieg | Begründung |
|---|---|---|
| VPC, Subnetz, VM oder Managed Database anlegen | **Terraform** | Ressourcenidentität, Abhängigkeiten und geplanter Lebenszyklus |
| Pakete und Dateien auf vorhandenen Servern verwalten | **Ansible** | Inventory und wiederverwendbare Konfigurationsaufgaben |
| Wartungsschritte über mehrere Hosts koordinieren | **Ansible** | Geordnete Plays, Bedingungen und Betriebsabläufe |
| VMs erstellen und Anwendungen darin konfigurieren | **Beide** | Infrastruktur und Gastkonfiguration getrennt verwalten |
| Ausschließlich Managed oder Serverless Services betreiben | **Terraform, möglicherweise ohne Ansible** | Eventuell gibt es kein selbst verwaltetes Gastbetriebssystem |
| Anwendungen in eine bestehende GitOps-Plattform ausrollen | **Den Deployment-Ablauf der Plattform nutzen** | Ein zusätzlicher Verwalter derselben Objekte kann Konflikte erzeugen |

Das ist eine Rangfolge **nach Aufgabe**, keine Punktewertung. Sobald klar ist, was sich ändern soll und wer es anschließend betreibt, lässt sich „Was ist besser?“ sinnvoll beantworten.

## Fünf Grundbegriffe ohne Vorwissen

**Infrastructure as Code (IaC)** bedeutet, Infrastruktur in versionierten Dateien zu beschreiben, damit Änderungen überprüfbar und wiederholbar werden. **Provisionierung** erstellt oder verändert Ressourcen wie Netzwerke, virtuelle Maschinen oder Datenbanken. **Konfigurationsmanagement** bringt ausgewählte Einstellungen eines Systems auf ihren Sollwert: Ein Paket ist installiert, eine Datei hat bestimmten Inhalt, ein Dienst startet automatisch.

Der **Sollzustand** beschreibt das gewünschte Ergebnis. **Drift** bezeichnet Abweichungen zwischen dieser Absicht und dem tatsächlichen Zustand. Beide Begriffe helfen bei beiden Werkzeugen; sie gehören nicht exklusiv zu Terraform.

Als Bild eignet sich ein Gebäude: Terraform verwaltet häufig Grundstück, Rohbau und Anschlüsse. Ansible richtet häufig die Ausstattung ein. Die Analogie hat Grenzen: Beide Werkzeuge können APIs ansprechen, und manche Infrastruktur benötigt überhaupt keinen konfigurierbaren Gast.

![Ansible vs Terraform Architektur: Terraform steuert Cloud-Ressourcen über APIs; Ansible konfiguriert Pakete, Dateien und Dienste auf Hosts aus einem Inventory.](https://www.alekseialeinikov.com/blog/ansible-vs-terraform-boundary.webp "Der Lebenszyklus einer Ressource und die Konfiguration im Gast sind getrennte Verantwortlichkeiten – auch innerhalb desselben Teams.")

## Was Terraform tatsächlich macht

Du schreibst Konfiguration, üblicherweise in **HCL**. **Provider** verbinden Terraform mit den APIs von Cloud- und anderen Diensten. Eine `resource` beschreibt ein verwaltetes Objekt, eine `data`-Quelle liest Informationen. Referenzen zwischen Werten stellen Abhängigkeiten her. Terraform kann dadurch Operationen ordnen, ohne dass du jede Reihenfolge als Shell-Skript formulieren musst. [Terraform-Einführung](https://developer.hashicorp.com/terraform/intro)

Der typische Ablauf:

```bash
terraform init
terraform plan -out=reviewed.tfplan
terraform apply reviewed.tfplan
```

`init` bereitet Arbeitsverzeichnis und Provider vor. `plan` schlägt Änderungen vor. Das Anwenden des gespeicherten Plans führt die geprüften Aktionen aus. Berechtigungen, Quoten, Verfügbarkeit oder veränderte Bedingungen können trotzdem zu Fehlern führen. Prüfe insbesondere Ersetzungen und Löschungen, nicht nur die Gesamtzahl der Änderungen. [Plan-Referenz](https://developer.hashicorp.com/terraform/cli/commands/plan)

Hinzu kommt der **State**. Er verbindet eine Konfigurationsadresse wie `aws_instance.web` mit der Identität einer tatsächlichen Ressource. Terraform sucht nicht einfach nach einem Objekt mit passendem Anzeigenamen. Der State enthält außerdem Informationen für spätere Operationen und ist deshalb eine betriebliche Abhängigkeit, kein beliebig löschbarer Cache. [State-Dokumentation](https://developer.hashicorp.com/terraform/language/state)

Nach dem Ende von `apply` überwacht Terraform CLI deine Cloud nicht dauerhaft. Eine erneute Ausführung, ein geplanter Job oder eine Plattformfunktion muss wieder nach Abweichungen suchen. Der kontinuierliche Abgleich von [Argo CD und Flux](https://www.alekseialeinikov.com/de/blog/topics/devops/argo-cd-vs-flux-vergleich) ist ein anderes Betriebsmodell.

## Was Ansible tatsächlich macht

Am Anfang steht ein **Inventory**: Hosts und Gruppen mit Verbindungsdaten und Variablen. Ein **Playbook** enthält Plays, die Ziele auswählen und Tasks ausführen. Ein **Modul** übernimmt eine bestimmte Aktion; **Collections** bündeln Module und Plugins. Rollen strukturieren wiederverwendbare Automatisierung. [Ansible-Grundbegriffe](https://docs.ansible.com/projects/ansible/latest/getting_started/basic_concepts.html)

Für einen Linux-Server könnten die Aufgaben so aussehen:

```yaml title="configuration-fragment.yml"
- name: Ensure nginx is installed
  ansible.builtin.apt:
    name: nginx
    state: present

- name: Ensure nginx runs at boot and now
  ansible.builtin.service:
    name: nginx
    enabled: true
    state: started
```

Das sind Sollzustandsbeschreibungen, obwohl die Reihenfolge der Tasks ebenfalls relevant ist. Unter der Standardstrategie führt Ansible Aufgaben normalerweise in Playbook-Reihenfolge aus; Strategien und weitere Einstellungen beeinflussen das Verhalten. [Playbook-Dokumentation](https://docs.ansible.com/projects/ansible/latest/playbook_guide/playbooks_intro.html)

**Agentless** bedeutet, dass ein normal verwalteter Linux-Host keinen dauerhaft laufenden Ansible-Daemon benötigt. Eine funktionierende Verbindung, passende Berechtigungen und Modulabhängigkeiten bleiben notwendig, häufig auch Python. Windows, Netzwerkgeräte und API-Module können andere Transportwege oder Ausführungsorte nutzen. Auch der Control Node muss gepflegt werden.

Unterscheide außerdem **ansible-core**, das **Ansible-Community-Paket** und **Red Hat Ansible Automation Platform**. Core enthält Laufzeit und eingebaute Plugins, das Community-Paket ausgewählte Collections. Die Enterprise-Plattform ergänzt eine unterstützte Betriebsumgebung und organisatorische Funktionen. Das sind keine austauschbaren Produktbezeichnungen. [Releases und Wartung](https://docs.ansible.com/projects/ansible/latest/reference_appendices/release_and_maintenance.html)

## Die Unterschiede nach dem ersten Tutorial

| Aspekt | Terraform | Ansible |
|---|---|---|
| Typische Verantwortung | API-Ressource und ihr Lebenszyklus | Ausgewählte Einstellungen und Betriebsaufgaben |
| Konfiguration | HCL; auch JSON-Syntax möglich | YAML-Playbooks, Variablen und Inventory |
| Koordination | Abhängigkeitsgraph und persistenter Ressourcen-State | Plays, Inventory, Module, Bedingungen und Strategie |
| Typische Verbindung | Provider authentifiziert sich an einer API | SSH, andere Transporte oder API-Aufrufe je nach Modul |
| Vorschau | Ressourcenplan über Provider | Check/Diff für unterstützte Tasks |
| Wiederholung | Prüft verwaltete Ressourcen und plant Unterschiede | Prüft Tasks erneut; Verhalten hängt von Modulen und Code ab |
| Objekt aus Eingabe entfernen | Entfernter Ressourcenblock führt üblicherweise zu geplantem Löschen | Ein entfernter Inventory-Host wird nicht gelöscht |
| Dauerhafte Durchsetzung | Benötigt zusätzliche Ausführungen oder Zeitplanung | Benötigt bei üblichem Push-Betrieb zusätzliche Ausführungen oder Zeitplanung |
| Wiederverwendung | Module | Rollen und Collections |
| Betriebsaufwand | State, Provider-Versionen, Berechtigungen und Lebenszyklusprüfung | Inventory, Zugangsdaten, Laufzeit, Collections und Task-Qualität |

### Deklarativ gegen imperativ erklärt zu wenig

Eine Terraform-Ressource beschreibt ein gewünschtes Objekt. Ein Ansible-Task mit `apt` und `state: present` beschreibt ebenfalls einen Sollzustand. Ein Shell-Aufruf in Ansible kann dagegen beliebige Aktionen ausführen; ihre Sicherheit entsteht nicht durch das YAML-Format.

**Idempotenz** bedeutet, dass eine wiederholte Operation bei gleichen relevanten Bedingungen das Ergebnis nicht immer weiter verändert. Ein Modul mit festem Dateiinhalt kann idempotent sein. Ein Befehl, der bei jedem Lauf eine Zeile anhängt, wird nicht dadurch idempotent, dass Ansible ihn startet.

Ein leerer Terraform-Plan bedeutet, dass für die verwalteten Ressourcen und Attribute keine Änderungen vorgeschlagen werden. Er beweist weder ein unverändertes Gastbetriebssystem noch eine funktionierende Anwendung.

> [!KEY]
> Automatisierung wird vertrauenswürdiger, wenn ihre Zuständigkeit eindeutiger ist als die Liste ihrer technischen Möglichkeiten.

### State und Inventory unterscheiden sich nicht nur im Dateiformat

Terraform-State speichert Ressourcenidentität. Das Ansible-Inventory bestimmt die Ziele. Ein Inventory kann automatisch aus Cloud-APIs entstehen, wird dadurch aber nicht zu Terraform-State. [Inventory-Anleitung](https://docs.ansible.com/projects/ansible/latest/inventory_guide/intro_inventory.html)

Das zeigt sich beim Löschen: Verschwindet eine VM aus einer Ansible-Gruppe, wird sie nicht mehr angesprochen, bleibt aber bestehen. Entfernst du eine Terraform-verwaltete VM aus der Konfiguration, schlägt der nächste Plan normalerweise ihre Zerstörung vor. **Löschpläne immer lesen.** Lifecycle-Einstellungen und bewusste State-Operationen können dieses Verhalten beeinflussen; zum Experimentieren gehört eine isolierte Umgebung. [Lifecycle-Referenz](https://developer.hashicorp.com/terraform/language/meta-arguments/lifecycle)

Vorhandene Ressourcen lassen sich über Import unter Terraform-Verwaltung bringen. Auch dafür braucht es passende Konfiguration und Prüfung. Import macht nicht auf Knopfdruck ein ganzes Cloud-Konto sicher verwaltet. [Import-Überblick](https://developer.hashicorp.com/terraform/language/import)

## Terraform plan und Ansible --check im Vergleich

Terraform plant Ressourcenoperationen anhand von Konfiguration, State und Provider-Abfragen. Manche Werte stehen erst während `apply` fest. Ein Plan führt keine beliebige Konfiguration innerhalb des Gasts aus.

Ansible `--check` lässt unterstützte Module Änderungen vorhersagen. `--diff` zeigt dort, wo es unterstützt wird, Vorher/Nachher-Unterschiede. Abhängigkeiten von Ergebnissen vorheriger Tasks können eine Simulation einschränken. Ein Task kann den Check-Modus außerdem ausdrücklich umgehen. [Check- und Diff-Modus](https://docs.ansible.com/projects/ansible/latest/playbook_guide/playbooks_checkmode.html)

```bash
ansible-playbook -i inventory.json site.yml --check --diff
```

Nutze beide Vorschauen und ergänze Anwendungstests. Ein erfolgreiches Apply und ein Playbook ohne Fehler beweisen noch nicht, dass DNS, TLS, Backend oder Zugriffsrechte richtig funktionieren.

## Praxisbeispiel: Terraform erstellt eine VM, Ansible konfiguriert nginx

Das Beispiel verwendet eine **private Ubuntu-EC2-Instanz**. Terraform besitzt den VM-Lebenszyklus. Ansible verwaltet nginx, eine statische HTML-Datei und den laufenden/aktivierten Dienst. Bestehendes Netzwerk und SSH-Zugang werden als Voraussetzungen bereitgestellt.

Lade [main.tf](https://www.alekseialeinikov.com/examples/ansible-vs-terraform/main.tf), [site.yml](https://www.alekseialeinikov.com/examples/ansible-vs-terraform/site.yml), [Beispielvariablen](https://www.alekseialeinikov.com/examples/ansible-vs-terraform/terraform.tfvars.example) und die [vollständigen Einrichtungs- und Aufräumhinweise](https://www.alekseialeinikov.com/examples/ansible-vs-terraform/README.txt) herunter. Die Ausschnitte erklären die wichtigen Stellen; für den Ablauf gehören die vollständigen Dateien zusammen.

### 1. Voraussetzungen vorbereiten

Verwende ein separates Testkonto oder eine isolierte Laborumgebung. Benötigt werden Terraform, eine unterstützte Ansible/Python-Kombination, AWS-Zugangsdaten, eine freigegebene **Ubuntu-amd64-AMI in der gewählten Region**, ein vorhandenes Subnetz mit Security Group und ein EC2-Schlüsselpaar. Der private Schlüssel bleibt beim Controller, möglichst im SSH-Agent.

Der Controller benötigt eine Route zur privaten IP, etwa über einen Runner in der VPC, ein VPN oder einen korrekt eingerichteten Bastion-Host. Erlaube SSH nur vom Controller und HTTP nur vom Testclient. Für Pakete braucht die VM kontrollierten DNS-/Repository-Zugriff über vorhandenen Egress oder einen Mirror. **Das Beispiel erstellt keine öffentliche IP, kein NAT Gateway, keine VPC und keine Firewallregeln.**

Prüfe den SSH-Hostschlüssel über einen vertrauenswürdigen Kanal und pflege `known_hosts`; schalte die Prüfung nicht ab. Das Image muss Python, apt und passende sudo-Rechte bereitstellen. Warte auf den Abschluss der initialen Image-Einrichtung. Die Cloud-Ressourcen sind kostenpflichtig; dies ist kein versprochenes Free-Tier-Labor.

### 2. Die VM mit Terraform beschreiben

Die vollständige Datei deklariert Provider und Variablen. Ihre zentrale Ressource:

```hcl title="main.tf · Ressourcenausschnitt"
resource "aws_instance" "web" {
  ami                         = var.ubuntu_ami_id
  instance_type               = "t3.micro"
  subnet_id                   = var.subnet_id
  vpc_security_group_ids       = [var.security_group_id]
  key_name                    = var.ssh_key_name
  associate_public_ip_address = false

  metadata_options {
    http_tokens = "required"
  }
  root_block_device {
    encrypted = true
  }
  tags = {
    Name = "ansible-terraform-demo"
  }
}
```

Die AMI-ID ist eine explizite Eingabe: Du wählst ein geprüftes Image statt stillschweigend das jeweils neueste. Verschlüsselter Root-Speicher und erforderliche IMDSv2-Tokens ersetzen keine saubere Konto-, Netzwerk- und IAM-Konfiguration. [Offizielle AWS-Provider-Dokumentation](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/instance)

Kopiere `terraform.tfvars.example` nach `terraform.tfvars` und ersetze sämtliche Platzhalter. Danach:

```bash
terraform init
terraform fmt -check
terraform validate
terraform plan -out=demo.tfplan
terraform apply demo.tfplan
```

State, sensible Variablendateien und gespeicherte Pläne gehören nicht in Git. Die geprüfte `.terraform.lock.hcl` dagegen schon: Sie hält die Provider-Auswahl für Team und CI fest. Lokaler State genügt hier für das Einpersonen-Labor; gemeinsamer Betrieb braucht ein abgesichertes Backend.

### 3. Ein Inventory als klare Übergabe exportieren

Terraform gibt nur die Verbindungsdaten aus, die Ansible braucht:

```hcl title="main.tf · Inventory-Ausgabe"
output "ansible_inventory" {
  value = {
    all = {
      children = {
        web = {
          hosts = {
            web1 = { ansible_host = aws_instance.web.private_ip }
          }
          vars = { ansible_user = "ubuntu" }
        }
      }
    }
  }
}
```

```bash
terraform output -json ansible_inventory > inventory.json
ansible-inventory -i inventory.json --graph
ansible web -i inventory.json -m ansible.builtin.wait_for_connection -a 'timeout=180'
```

Bei einer **benannten** Ausgabe liefert `terraform output -json` direkt deren Wert. Das YAML-Inventory-Plugin von Ansible akzeptiert standardmäßig auch `.json`. Ein privater Schlüssel wird nicht exportiert. Erzeuge das Inventory nach Infrastrukturänderungen neu, damit keine veraltete Adresse zum Ziel wird. [Terraform output](https://developer.hashicorp.com/terraform/cli/commands/output), [Ansible-Inventory-Plugin](https://docs.ansible.com/projects/ansible/latest/collections/ansible/builtin/yaml_inventory.html)

Der Verbindungstest wartet auf einen nutzbaren Ansible-Zugang. Eine erfolgreiche EC2-API-Antwort bedeutet noch nicht, dass der Gast bereit ist. Routing und die Prüfung unbekannter SSH-Hostschlüssel richtet der Task nicht ein. [wait_for_connection](https://docs.ansible.com/projects/ansible/latest/collections/ansible/builtin/wait_for_connection_module.html)

![Ansible mit Terraform: Geprüfter Plan, Apply, Inventory-Export, Verbindungsprüfung, Gastkonfiguration und Anwendungstest.](https://www.alekseialeinikov.com/blog/ansible-vs-terraform-workflow.webp "Das Inventory bildet eine schmale Übergabe. Ein separater HTTP-Test prüft das Ergebnis beider Automatisierungsschritte.")

### 4. Den Gast mit Ansible konfigurieren

Das vollständige Playbook wählt die Gruppe `web` und verwendet `become: true` für privilegierte Paket- und Dienstoperationen. Drei Tasks installieren nginx, veröffentlichen festen Inhalt und starten/aktivieren den Dienst.

```yaml title="site.yml · verwalteter Inhalt"
- name: Publish a deterministic home page
  ansible.builtin.copy:
    dest: /var/www/html/index.html
    content: "Infrastructure ready. Configuration managed.\n"
    owner: root
    group: root
    mode: "0644"
```

Explizite Dateirechte vermeiden eine Abhängigkeit von zufälligen Standardwerten. [Copy-Modul](https://docs.ansible.com/projects/ansible/latest/collections/ansible/builtin/copy_module.html)

```bash
ansible-playbook -i inventory.json site.yml --syntax-check
ansible-playbook -i inventory.json site.yml --ask-become-pass
ansible-playbook -i inventory.json site.yml --check --diff --ask-become-pass
ansible-playbook -i inventory.json site.yml --ask-become-pass
```

Bei passwortlosem sudo entfällt `--ask-become-pass`. Auf einer frischen VM sollte die echte Installation vor der vollständigen Check-Vorschau stattfinden: Das vom Paket angelegte Webverzeichnis existiert vorher möglicherweise noch nicht.

Der apt-Task nutzt `state: present` statt eines bedingungslosen Upgrades. `cache_valid_time` begrenzt Cache-Aktualisierungen; abgelaufene Caches oder Repository-Änderungen können spätere Läufe dennoch beeinflussen. Der Dienst-Task verlangt `started`, nicht `restarted`, und fordert damit keinen Neustart bei jeder Ausführung an. [Apt-Modul](https://docs.ansible.com/projects/ansible/latest/collections/ansible/builtin/apt_module.html), [Service-Modul](https://docs.ansible.com/projects/ansible/latest/collections/ansible/builtin/service_module.html)

Rufe vom berechtigten Testclient `http://PRIVATE_IP/` mit `curl --fail` auf. Die Adresse steht in `inventory.json`; die Antwort sollte dem verwalteten Text entsprechen. Das ist eine isolierte HTTP-Übung, keine internetfertige TLS-Konfiguration.

### 5. Wiederholung beobachten und aufräumen

Bei unveränderten Eingaben und stabiler Infrastruktur sollte der nächste Terraform-Plan keine Änderungen vorsehen. Ist der Gast eingerichtet, sollte der nächste Ansible-Lauf keine verwalteten Änderungen melden – abgesehen von Cache-Aktualisierungen oder geänderten äußeren Bedingungen. **Das sind selbst zu prüfende Erwartungen, keine hier gemessenen Ergebnisse.**

Ändere anschließend nur den Seitentext. Ansible sollte die Datei aktualisieren; Terraform sollte keine Änderung der Gastdatei planen. Dieses kleine Experiment macht die Verantwortungsgrenze sichtbar.

Prüfe zum Abschluss die Löschung im selben isolierten Arbeitsverzeichnis:

```bash
terraform plan -destroy -out=destroy.tfplan
terraform apply destroy.tfplan
```

Unter den Standardeinstellungen des Beispiels verschwinden die VM und ihr verwaltetes Root-Volume. Vorgegebene Netzwerkressourcen und das bestehende Schlüsselpaar liegen außerhalb der Konfiguration. Verbleibenden State und Backups schützen; erzeugte Inventories und Pläne entfernen, sobald sie nicht mehr benötigt werden.

## Was passiert bei einem Fehler auf halbem Weg?

Die VM wurde angelegt, aber nginx ließ sich wegen eines unerreichbaren Paketservers nicht installieren. Terraforms Infrastruktur-Erfolg ist damit noch kein Anwendungserfolg. Behebe die Verbindung, prüfe den Host und starte Ansible erneut. Die VM muss nicht automatisch neu erstellt werden.

Keiner der Abläufe ist eine Transaktion über die gesamte Anwendung. Frühere erfolgreiche Schritte können nach einem späteren Fehler bestehen bleiben. Ein Ansible-Rollout kann manche Hosts aktualisiert haben, andere nicht. Eine Terraform-Ersetzung kann abhängige Ressourcen betreffen. Deshalb brauchen beide Wiederherstellungsschritte und Gesundheitstests.

| Symptom | Zuerst prüfen | Vermeiden |
|---|---|---|
| VM existiert, SSH läuft ins Timeout | Route, Security Group, Benutzer/Schlüssel, Gastbereitschaft | Hostschlüsselprüfung als vermeintliche Netzwerklösung abschalten |
| Terraform will eine VM ersetzen | Geänderte Attribute und Provider-Verhalten | Ohne Prüfung von Daten und Verfügbarkeit anwenden |
| Ansible meldet jedes Mal Änderungen | Modulsemantik, generierte Inhalte, Cache-Ablauf | Änderungen blind mit `changed_when: false` verstecken |
| Automatisierung erfolgreich, HTTP fehlerhaft | Dienst, Listen-Adresse, Netzwerkpfad, Anwendungslogs | Zusammenfassung mit Funktionstest gleichsetzen |
| Zwei Deployments laufen gleichzeitig | Backend-Locking und Job-Koordination | Unabhängige Schreiber für dieselben Ziele |

Soll eine Konfigurationsänderung einen Dienst neu laden, nutze einen davon benachrichtigten Handler statt eines Neustarts bei jedem Lauf. Handler koordinieren Aktionen, bieten aber kein automatisches Rollback. [Ansible-Handler](https://docs.ansible.com/projects/ansible/latest/playbook_guide/playbooks_handlers.html)

## Ansible und Terraform gemeinsam einsetzen

Eine klare Aufteilung lautet: **Ressourcenlebenszyklus → Verbindungsvertrag → Gastkonfiguration → Gesundheitstest**. HashiCorp dokumentiert auch ein umfangreicheres Integrationsmuster mit HCP Terraform und Ansible Automation Platform. Dieses Muster stützt die Grundidee; zum Verständnis der Übergabe benötigst du nicht beide Enterprise-Plattformen. [Offizielles Integrationsmuster](https://developer.hashicorp.com/validated-patterns/terraform/terraform-integrate-ansible-automation-platform)

Halte die Zuständigkeiten fest:

- Terraform verwaltet Erstellung/Löschung der VM und die in seiner Konfiguration beschriebenen Cloud-Ressourcen.
- Ansible verwaltet ausdrücklich ausgewählte Pakete, Dateien, Konten und Dienste im Gast.
- Eine Pipeline prüft die Übergabe, koordiniert gleichzeitige Ausführungen und protokolliert Ergebnisse.
- Ein Anwendungstest prüft, ob der Dienst tatsächlich funktioniert.

Vermeide einen Ansible-Task, der dasselbe Cloud-Attribut wie Terraform verändert. Ebenso sollten cloud-init und Ansible nicht bei jedem Boot dieselbe Datei überschreiben. Das Problem sind konkurrierende Verantwortlichkeiten, auch wenn jeder einzelne Schreiber zuverlässig funktioniert.

### Warum nicht alles aus einem Terraform-Provisioner starten?

`local-exec` kann Ansible aufrufen. Dadurch werden aber nicht alle Einstellungen im Gast Teil von Terraforms Ressourcenmodell. Konfigurationsfehler werden zusätzlich mit dem Infrastrukturlebenszyklus gekoppelt; Wiederholungen oder Ersetzungen können unerwartet wirken. HashiCorp empfiehlt Provisioner als letzte Option, wenn bessere Mechanismen fehlen. [Provisioner-Empfehlungen](https://developer.hashicorp.com/terraform/language/provisioners)

Bevorzuge eine separate Pipeline-Stufe, eine geeignete Integration oder einen Image-/Bootstrap-Ablauf. **cloud-init** passt zu einem kleinen initialen Bootstrap. **Image-Building** passt, wenn ein vorbereitetes System besser ersetzt als fortlaufend verändert wird. Die Entscheidung gehört zur Architektur; „Alle Befehle passen in eine `.tf`-Datei“ genügt nicht als Wartungskonzept.

## Sicherheit: Beide Werkzeuge besitzen echte Berechtigungen

Terraform-State und gespeicherte Pläne können Geheimnisse enthalten. `sensitive = true` unterdrückt normale Anzeigen, verschlüsselt den Wert aber nicht automatisch und verhindert nicht grundsätzlich seine Speicherung. Unterstützte **ephemere** Mechanismen und Write-only-Argumente können die Persistenz in bestimmten Abläufen vermeiden; dafür müssen Terraform und Provider die benötigten Funktionen unterstützen. [Sensible Daten](https://developer.hashicorp.com/terraform/language/manage-sensitive-data), [Ephemere Werte](https://developer.hashicorp.com/terraform/language/manage-sensitive-data/ephemeral)

Im Team braucht das Backend Verschlüsselung, Zugriffskontrolle und unterstütztes Locking. Ein Lock schützt State vor gleichzeitigen Schreibern; es koordiniert nicht jedes andere Werkzeug mit Zugriff auf Cloud oder Gast. Backups und ein getesteter Wiederherstellungsablauf bleiben nötig. [State-Locking](https://developer.hashicorp.com/terraform/language/state/locking)

Auch Ansible-Variablen, Debug-Ausgaben, Diffs und Zugangsdaten können Informationen preisgeben. **Ansible Vault** verschlüsselt Dateien und Variablen. Entschlüsselungszugriff und Laufzeitprotokolle brauchen trotzdem eigene Kontrollen. Es ist nicht derselbe Dienst wie HashiCorp Vault. [Ansible Vault](https://docs.ansible.com/projects/ansible/latest/vault_guide/vault.html)

Nutze möglichst kurzlebige Cloud-Zugangsdaten, prüfe SSH-Hosts, begrenze Rechteausweitung und kontrolliere Provider-/Collection-Abhängigkeiten. Der Runner führt Automatisierung mit den Rechten seiner Zugangsdaten aus. Der [GitLab-CI/CD-Härtungsleitfaden](https://www.alekseialeinikov.com/de/blog/topics/devops/sichere-gitlab-cicd-pipelines-hardening-playbook-2026) behandelt diese Ausführungsgrenze; [Workload Identity Federation](https://www.alekseialeinikov.com/de/blog/topics/security/service-account-schluessel-abschaffen-workload-identity-federation-2026) erklärt die Ablösung langlebiger Cloud-Schlüssel.

## Was sollten Einsteiger zuerst lernen?

![Ansible vs Terraform Entscheidungshilfe: Vorhandene Server führen zu Ansible, neue Cloud-Ressourcen zu Terraform und kombinierte Anforderungen zu beiden.](https://www.alekseialeinikov.com/blog/ansible-vs-terraform-decision.webp "Wähle das erste Werkzeug anhand deiner nächsten Aufgabe. Lerne die Übergabe, sobald die zweite Verantwortung hinzukommt.")

**Beginne mit Ansible, wenn Server bereits existieren.** Verwalte eine Datei, ein Paket und einen Dienst und führe das Playbook zweimal aus. Verändere etwas in einer wegwerfbaren Umgebung und beobachte die Reparatur. Lerne Inventory, Variablen, Rechteausweitung und Handler vor einer großen Rollenbibliothek.

**Beginne mit Terraform, wenn Infrastruktur fehlt.** Erstelle eine kleine isolierte Ressource, lies den Plan und ändere ein Attribut. Sieh dir den State an, ohne ihn manuell zu bearbeiten. Übe den Unterschied zwischen Aktualisierung, Ersetzung und Löschung. Berechtigungen und Backend-Betrieb gehören ebenso zum Lernen wie HCL.

**Lerne beide, wenn deine Aufgaben die Grenze überschreiten.** Provisioniere eine VM, exportiere ein kleines Inventory und konfiguriere einen Dienst. Trenne die Schritte so, dass ein Konfigurations-Retry keinen Infrastruktur-Neuaufbau erfordert.

| Lernschritt | Was du erklären können solltest |
|---|---|
| Vor dem ersten Werkzeug | IP-Adressen, DNS, SSH, Berechtigungen, Git und getrennte Umgebungen |
| Erste Terraform-Übung | Was entsteht, welche Rechte es erlauben, wo State liegt und wie die Löschung funktioniert |
| Erste Ansible-Übung | Welche Hosts betroffen sind, was sich ändert und warum eine Wiederholung stabil bleibt |
| Erste Kombination | Zuständigkeit, Adressübergabe und Bereitschaftsprüfung |
| Vor Produktion | Wiederherstellung, Geheimnisse, Reviews, feste Abhängigkeiten und Parallelitätskontrolle |

Einen allgemeinen Geschwindigkeits- oder Kostensieger gibt es nicht. Provider-APIs, Hostanzahl, Verbindungslatenz, Task-Design und gewählte Plattformen beeinflussen das Ergebnis. Eine Stoppuhr für unterschiedliche Aufgaben wäre kein hilfreicher Vergleich.

## Kosten, Lizenzen und benachbarte Werkzeuge

Trenne CLI, Plattform und Cloud-Rechnung. Community-Ansible benötigt kein Automation-Platform-Abonnement. Terraform CLI und kommerzielle HCP-Terraform-Funktionen sind ebenfalls unterschiedliche Fragen. Organisationen sollten die jeweiligen Lizenzen und Bedingungen prüfen; „herunterladbar“ bedeutet nicht „uneingeschränkt“. [Ansible-Lizenz](https://github.com/ansible/ansible/blob/devel/COPYING), [Terraform-Lizenz](https://github.com/hashicorp/terraform/blob/main/LICENSE)

Geht es um Terraform-Governance oder Lizenzierung, hilft [OpenTofu vs Terraform](https://www.alekseialeinikov.com/de/blog/topics/devops/opentofu-vs-terraform-lohnt-der-fork-2026). Das ist eine Entscheidung innerhalb der Provisionierungsschicht und unabhängig davon, ob Ansible die Gastkonfiguration übernimmt.

Bei Kubernetes kann Terraform die Infrastruktur aufbauen und Ansible Vorbereitung oder Wartung automatisieren. Anwendungen werden möglicherweise bereits durch Helm, Argo CD oder Flux ausgeliefert. Ein kleines Projekt muss nicht jedes Werkzeug einer Ökosystemgrafik einsetzen. Ergänze ein Werkzeug dann, wenn es eine konkrete Verantwortung klarer und besser betreibbar macht.

## Erst Zuständigkeiten, dann der Gewinner

Terraform ist ein starker Ausgangspunkt für **vorhandene Infrastruktur und ihren Lebenszyklus**. Ansible ist ein starker Ausgangspunkt für **gewünschte Systemeinstellungen und auszuführende Betriebsaufgaben**. Überschneidungen sind möglich, gemeinsame Schreibverantwortung ist deshalb noch lange nicht nötig.

Für Einsteiger reicht zunächst eine kleine vollständige Übung: Maschine anlegen, Dienst konfigurieren, beides wiederholen, eine Sache ändern und aufräumen. Wenn du erklären kannst, welches Werkzeug jede Änderung erkennt und wie du einen Fehler im zweiten Schritt behebst, kannst du eine begründete Wahl treffen.
