Das Problem: Snowflake-Server
Jeder, der in der Softwareentwicklung arbeitet, kennt das Szenario: Der Produktionsserver, den nur eine Person konfiguriert hat, die inzwischen nicht mehr im Unternehmen ist. Hunderte von manuellen Anpassungen, undokumentiert, Schicht für Schicht entstanden. Diesen Server kann niemand reproduzieren. Er ist ein Snowflake, einzigartig, fragil und im Fehlerfall nicht wiederherstellbar.
Infrastructure as Code (IaC) löst dieses Problem, indem die gesamte Infrastruktur in versionierten, ausführbaren Dateien beschrieben wird. Kein manuelles Klicken in der AWS Console, keine SSH-Sessions, in denen “nur kurz etwas angepasst wird”. Die Infrastruktur ist Code, und damit gelten dieselben Qualitätsmaßstäbe wie für Anwendungscode: Reviews, Versionierung, Tests und automatisierte Deployments.
Terraform: Infrastruktur provisionieren
Terraform von HashiCorp ist ein deklaratives Tool zur Provisionierung von Infrastruktur. Man beschreibt den gewünschten Zustand, und Terraform berechnet den Weg dorthin.
resource "aws_instance" "app_server" {
ami = "ami-0c55b159cbfafe1f0"
instance_type = "t3.medium"
subnet_id = aws_subnet.private.id
tags = {
Name = "app-server-prod"
Environment = "production"
ManagedBy = "terraform"
}
}
resource "aws_security_group" "app" {
name_prefix = "app-"
vpc_id = aws_vpc.main.id
ingress {
from_port = 8080
to_port = 8080
protocol = "tcp"
cidr_blocks = [aws_subnet.private.cidr_block]
}
}
Die Stärke von Terraform liegt im State Management. Terraform speichert den aktuellen Zustand der Infrastruktur und kann bei jeder Ausführung einen Plan erstellen, der zeigt, welche Änderungen vorgenommen werden. Das macht Infrastrukturänderungen vorhersagbar und reviewbar.
Terraform State: Segen und Herausforderung
Der Terraform State ist gleichzeitig das mächtigste Feature und die größte Fehlerquelle. Er muss zentral und sicher gespeichert werden, ein lokaler State-File ist in Teamprojekten nicht praktikabel. S3 mit DynamoDB-Locking hat sich als robuste Lösung für AWS-Umgebungen etabliert:
terraform {
backend "s3" {
bucket = "terraform-state-prod"
key = "infrastructure/terraform.tfstate"
region = "eu-central-1"
encrypt = true
dynamodb_table = "terraform-locks"
}
}
Ansible: Server konfigurieren
Während Terraform die Infrastruktur provisioniert, also VMs, Netzwerke, Load Balancer erstellt, übernimmt Ansible die Konfiguration der erstellten Maschinen. Die Trennung ist wichtig: Terraform weiß, dass ein Server existieren soll. Ansible weiß, wie der Server konfiguriert sein soll.
Ansible arbeitet agentless über SSH und verwendet YAML-Playbooks:
- name: Configure application server
hosts: app_servers
become: true
tasks:
- name: Install Java 11
apt:
name: openjdk-11-jdk
state: present
- name: Create application user
user:
name: appuser
system: true
shell: /bin/false
- name: Deploy application
copy:
src: "{{ artifact_path }}"
dest: /opt/app/application.jar
owner: appuser
mode: '0644'
notify: Restart application
handlers:
- name: Restart application
systemd:
name: application
state: restarted
Idempotenz: Der Schlüssel zu zuverlässiger Automatisierung
Ein fundamentales Prinzip sowohl von Terraform als auch von Ansible ist Idempotenz. Eine Operation ist idempotent, wenn sie bei mehrfacher Ausführung dasselbe Ergebnis liefert wie bei einmaliger Ausführung. Das bedeutet: Ein Playbook kann beliebig oft ausgeführt werden, ohne unerwünschte Seiteneffekte zu erzeugen.
In der Praxis heißt das:
apt: state=presentinstalliert ein Paket nur, wenn es noch nicht installiert istterraform applyändert nur Ressourcen, die vom gewünschten Zustand abweichen- Ein korrekt geschriebenes Playbook kann als Drift Detection dienen, es zeigt an, ob sich etwas am System verändert hat
GitOps: Die Infrastruktur im Repository
Die konsequente Umsetzung von IaC führt zu GitOps: Die gesamte Infrastruktur wird in einem Git-Repository verwaltet. Änderungen erfolgen über Pull Requests, werden reviewed und nach dem Merge automatisch angewendet.
Der typische Workflow sieht so aus:
- Branch erstellen, Feature-Branch für die Infrastrukturänderung
- Änderung implementieren, Terraform-Konfiguration oder Ansible-Playbook anpassen
- Plan erstellen,
terraform planzeigt die geplanten Änderungen - Review, Kollegen prüfen den Plan und den Code
- Merge, Nach Approval wird der Branch gemergt
- Apply, Die CI/CD-Pipeline wendet die Änderungen automatisch an
Dieser Workflow bringt dieselbe Nachvollziehbarkeit in die Infrastruktur, die wir im Anwendungscode längst praktizieren. Jede Änderung ist dokumentiert, reviewt und reproduzierbar.
Reproduzierbare Umgebungen: Dev, Staging, Prod
Einer der größten praktischen Vorteile von IaC ist die Möglichkeit, identische Umgebungen für Development, Staging und Production zu erstellen. In Terraform lässt sich das über Workspaces oder Module-Parametrisierung umsetzen:
module "environment" {
source = "./modules/app-environment"
environment = var.environment # "dev", "staging", "prod"
instance_type = var.environment == "prod" ? "t3.large" : "t3.small"
instance_count = var.environment == "prod" ? 3 : 1
enable_monitoring = var.environment == "prod" ? true : false
}
Die Umgebungen unterscheiden sich in Größe und Redundanz, aber die Architektur ist identisch. Das eliminiert die klassische Aussage “Aber auf meiner Maschine funktioniert es”, oder zumindest verschiebt sie auf eine beherrschbare Ebene.
Fazit
Infrastructure as Code ist kein optionales Nice-to-have, sondern eine Grundvoraussetzung für professionelle Softwareentwicklung. Die Kombination aus Terraform für die Provisionierung und Ansible für die Konfiguration deckt den gesamten Lebenszyklus ab. Der initiale Aufwand für die Einführung von IaC ist signifikant, wird aber durch reproduzierbare Umgebungen, nachvollziehbare Änderungen und die Möglichkeit zur Automatisierung schnell ausgeglichen. Wer heute noch Server manuell konfiguriert, arbeitet mit einem Risiko, das nicht mehr zeitgemäß ist.