ADMIN

2024

11

2024-10-30T12:00:00

Cloudmanagement

SCHWERPUNKT

085

Cloud

Terraform

Nahtlose Deployments mit Terraform

Geschmeidiger Übergang

von Philip Lorenz

Veröffentlicht in Ausgabe 11/2024 - SCHWERPUNKT

Mit Konzepten wie Rolling beziehungsweise Incremental Updates oder Zero-Downtime-Deployments vollziehen sich Aktualisierungen in Applikationen und Diensten unterbrechungsfrei und für den Anwender unbemerkt im Hintergrund. Wir zeigen, wie sich derartige Updates in der Praxis umsetzen lassen und wie Infrastructure-as-Code mit Terraform dies unterstützt.

Zero-Downtime-Deployment (ZDD) beschreibt den nahtlosen Prozess, Systeme ohne Unterbrechungen oder Ausfallzeiten zu migrieren oder zu aktualisieren. Die Dienste bleiben während des gesamten Übergangs zugänglich und funktional. ZDD ist entscheidend für die Aufrechterhaltung einer unterbrechungsfreien Benutzererfahrung und gewährleistet reibungslose Übergänge ohne Störungen. Die Vorteile liegen auf der Hand:
- Anwendungen bleiben während des gesamten Deployments online und verfügbar. Dies ist besonders wichtig für Unternehmen, die eine 24/7-Verfügbarkeit benötigen, wie E-Commerce-Websites oder SaaS-Anbieter.
- Falls ein Problem mit der neuen Version auftritt, kann oft schnell und ohne Benutzerbeeinträchtigung auf die vorherige Version zurückgesetzt werden. Warum das Rollback einfacher ist, erläutern wir im weiteren Verlauf des Artikels.
Zero-Downtime-Deployment (ZDD) beschreibt den nahtlosen Prozess, Systeme ohne Unterbrechungen oder Ausfallzeiten zu migrieren oder zu aktualisieren. Die Dienste bleiben während des gesamten Übergangs zugänglich und funktional. ZDD ist entscheidend für die Aufrechterhaltung einer unterbrechungsfreien Benutzererfahrung und gewährleistet reibungslose Übergänge ohne Störungen. Die Vorteile liegen auf der Hand:
- Anwendungen bleiben während des gesamten Deployments online und verfügbar. Dies ist besonders wichtig für Unternehmen, die eine 24/7-Verfügbarkeit benötigen, wie E-Commerce-Websites oder SaaS-Anbieter.
- Falls ein Problem mit der neuen Version auftritt, kann oft schnell und ohne Benutzerbeeinträchtigung auf die vorherige Version zurückgesetzt werden. Warum das Rollback einfacher ist, erläutern wir im weiteren Verlauf des Artikels.
- Das Minimieren von Ausfallzeiten und Unterbrechungen sorgt für eine konstante Qualität des Service, während sich die Anwendungen gleichzeitig kontinuierlich verbessern und weiterentwickeln lassen.
Das Vorgehen birgt aber auch mehrere Herausforderungen, die zwar nicht exklusiv für ZDD gelten, aber dennoch unbedingt zu beachten sind. Als Erstes sind hier Änderungen an der Datenbankstruktur wie etwa Schemaänderungen zu nennen. Diese müssen IT-Verantwortliche so umsetzen, dass die jeweilige Anwendung derartige Anpassungen sowohl von der alten als auch von der neuen Version unterstützt. Dies kann komplex sein, da die Datenbank und die Anwendung in einem kompatiblen Zustand bleiben müssen, bis der Wechsel vollständig erfolgt ist.
Die zweite Herausforderung liegt darin, dass Benutzer, die während des Deployments mit der Applikation arbeiten, keine Unterbrechungen erfahren dürfen. Das bedeutet, dass Sitzungen und Zustandsdaten korrekt zwischen den Versionen zu übertragen sind.
Rolling Updates
Für Zero Downtime Deployments gibt es verschiedene Strategien. Die bekanntesten sind hierbei Rolling Updates und Blue-Green-Deployments. Rolling Updates führen neue Versionen schrittweise in eine bestehende Deployment-Umgebung ein und nehmen alte Versionen nach und nach außer Betrieb. Diese Strategie zielt darauf ab, neue Versionen in ein bestehendes Deployment zu integrieren. Dabei entsteht ein heterogener Pool aus alten und neuen Versionen, mit dem Ziel, nach und nach alle alten Instanzen durch neue zu ersetzen. Die Begriffe "Instanz" und "Pool" können je nach Technologie-Stack unterschiedliche Bedeutungen haben, etwa VMs, Container, Prozesse et cetera.
Ein wichtiger Aspekt dieser Strategie ist das Health Checking und Monitoring. Der Sinn des schrittweisen Einführens neuer Versionen besteht darin, Schäden im Fall unerwarteter Probleme mit der neuen Version kontrollieren zu können. Dazu ist es erforderlich, zu wissen, wie die neue Version sich verhält. Daher sind Health Checks und Monitoring unerlässlich. Und falls Admins feststellen, dass das Deployment nicht wie gewünscht verläuft, können sie den Rollout stoppen und das Deployment sogar rückgängig machen (sogenanntes Rollback).
Da neue und alte Versionen nebeneinander im selben System laufen, kann es passieren, dass Benutzer willkürlich auf eine der beiden Versionen zugreifen. Deshalb sollte die Abwärtskompatibilität eine zentrale Rolle spielen, wenn diese Strategie verwendet wird.
Bild 1: Schema der drei Schritte einer Anwendungsaktualisierung mit Rolling Updates.
Blue-Green-Deployments
Blue-Green-Deployments richten eine neue, separate Umgebung für die neue Version ein, ohne die aktuelle Landschaft zu beeinflussen. Diese Version wird getestet und sobald sie bereit ist, den Benutzern bereitgestellt. Diese Strategie gilt als die sicherste und kommt häufig für Produktions-Workloads zum Einsatz. Um die Sicherheit zu gewährleisten, bleibt die aktuell laufende Version unverändert. Stattdessen steht eine vollständige Kopie der Anwendung oder des zu aktualisierenden Moduls bereit. Der Umfang des Deployments (oder der Isolation) kann variieren: Es ist festzulegen, ob das gesamte System oder nur das aktualisierte Modul neu erstellt wird. Ein anderer Aspekt umfasst den Ansatz, einen separaten Loadbalancer für die neue Version zu nutzen oder eine neue Regel im bestehenden. Zudem ist zu entscheiden, ob sich die Versionen die Konfiguration teilen. Diese Fragen müssen Sie je nach Situation und eingesetzten Tools entscheiden.
Der wichtigste Punkt ist, dass die neue Version vollständig isoliert von der aktuellen Umgebung ist. Im Gegensatz zu Rolling Updates, bei denen während des Upgrades alte und neue Versionen gleichzeitig laufen, ist dies hier nicht der Fall. Daher ist Rückwärtskompatibilität nicht zwingend erforderlich. Sobald die neue Version bereit ist, sollten Sie diese so lange wie nötig testen. Da die aktuelle Version weiterhin läuft und die Dienste bereitstellt, besteht kein Zeitdruck, das Deployment abzuschließen. Bewerten Sie die neue Version als stabil und qualitativ hochwertig genug, können Sie die Benutzer auf die neue Version umleiten. Dies kann entweder für alle Anwender gleichzeitig (auch als Cut-off oder Cut-over bezeichnet) oder schrittweise erfolgen, indem Sie nach und nach mehr User zur neuen Version leiten.
Ein oft übersehener Aspekt bei Blue-Green-Deployments betrifft die Lizenzierung. Manche Lizenzvereinbarungen verbieten dieses Vorgehen von vornherein, da die Infrastruktur und damit die Applikationsserver doppelt vorhanden sind und somit ein doppeltes Lizenzvolumen erfordern. Es ist ratsam, dies im Vorfeld abzuklären.
Bild 2: Blue-Green-Deployments aktualisieren Anwendungen, ohne dass der Nutzer davon etwas mitbekommt.
ZDD mit Terraform
Terraform von HashiCorp dient zur Verwaltung von Infrastruktur als Code. Das Tool ermöglicht IT-Administratoren, Infrastruktur in deklarativen Konfigurationsdateien zu definieren, automatisch bereitzustellen und zu verwalten. Dies reduziert manuelle Konfigurationsfehler und verbessert die Konsistenz. Alle folgenden Beispiele funktionieren auch für den Terraform-Fork OpenTofu, der aufgrund der aktuellen Lizenzsituation bezüglich Terraform entstanden ist.
Terraform bietet umfassende Möglichkeiten zum Steuern von Ressourcen, die Sie erstellen, modifizieren oder entfernen können. Das Tool kann auf Änderungen in der Konfiguration reagieren, indem es bestehende Ressourcen anpasst, ohne dass diese neu angelegt werden müssen. Falls eine Anpassung der vorhandenen Ressource nicht direkt möglich ist, zerstört Terraform diese und erstellt sie neu. Dieses Vorgehen ist oft von Vorteil, da es Naming-Konflikte vermeidet. Im Kontext von Zero Downtime ist es jedoch unvorteilhaft.
Um dieses Problem zu umgehen, erlaubt Terraform die Verwendung von sogenannten Lifecycle-Hooks. Diese sind Konfigurationsoptionen, die das Verhalten von Ressourcen während ihres Lebenszyklus steuern. Sie bieten mehr Kontrolle darüber, wie und wann Ressourcen erstellt, aktualisiert und gelöscht werden. Ein solcher Hook ist "create_before_destroy", der das Standardvorgehen umkehrt und erst die neue Ressource erstellt, bevor die alte zerstört wird:
powershell
resource "azurerm_virtual_machine" "<Name der Ressource>" {
  // ... Andere Konfigurationen
  lifecycle {
    create_before_destroy = true
  }
}
Terraform dient üblicherweise der Bereitstellung von Infrastruktur und ist dabei völlig agnostisch gegenüber den darauf laufenden Anwendungen oder Diensten. Der Lifecycle-Hook "create_before_destroy" ermöglicht es, dass die alte Ressource wie etwa eine VM erst dann zerstört wird, wenn die neue Ressource erfolgreich läuft. Doch nur weil die neue VM bereitsteht, bedeutet das nicht automatisch, dass der darüberliegende Service oder die Applikation fehlerfrei verfügbar sind.
Provisioners in Terraform sind spezielle Konfigurationselemente, die spezifische Aufgaben auf einer Maschine erledigen, nachdem diese erstellt oder aktualisiert wurde. Provisioners erlauben es, Skripte oder Befehle auszuführen, um zusätzliche Software zu installieren, Konfigurationsdateien zu ändern oder andere betriebliche Aufgaben zu erledigen. Mit ihrer Hilfe implementieren Sie einen Health Check, den Sie beispielsweise als Shell-Skript definieren (Listing 1)
Listing 1: Health Check als Shell-Skript
resource "aws_instance" "<Name der Ressource>" {
  # ... Andere Konfigurationen
  provisioner "remote-exec" {
    inline = [
      "echo 'Health Check: Running...'",
      "if curl -s http://localhost:8080/health | grep 'OK'; then exit 0; else exit 1; fi"
    ]
    connection {
      type     = "ssh"
      user     = "ubuntu"
      private_key = file("/path/to/private_key")
      host     = self.public_ip
    }
  }
  lifecycle {
    create_before_destroy = true
  }
}
Dieser Gesundheitsheck überprüft, ob ein lokaler Service auf Port 8080 eine "OK"-Antwort liefert. Falls ja, wird die Bereitstellung fortgesetzt. Andernfalls schlägt sie fehl und die alte Ressource bleibt bestehen. Dies stellt sicher, dass der neue Service tatsächlich fehlerfrei läuft, bevor er den alten ersetzt.
Blue-Green-Deployments in der Praxis
Blue-Green-Deployments gelten als die Königsdisziplin unter den Deployment-Strategien und werden auch von den Terraform-Entwicklern angewendet. Sie sind vergleichsweise einfach umzusetzen und bieten eine hohe Sicherheit und Flexibilität. In diesem Beispiel nutzen wir AWS mit den Ressourcen "aws_elb" (Elastic Load Balancing) und "aws_instance" (Server). Das Vorgehen ist aber auch auf anderen Plattformen möglich. In Listing 2 zeigt der Elastic Load Balancer (ELB) auf den Server namens "Blue". Nach diesem Deployment stellt Listing 3 die "Green"-Server als weitere Ressourcen bereit. Nach dem Deployment des Green-Servers schwenken wir das Routing des ELB auf den Green-Server und wenden es erneut an – dieser Prozess nennt sich Cutover:
powershell
resource "aws_elb" "main" {
  name = "blue-green-app-elb"
  // ... Andere Konfigurationen
  instances = [aws_instance.green.id]
}
Sobald Sie alles erfolgreich getestet haben, schicken Sie den Blue-Server in den Ruhestand, indem Sie ihn aus der Konfiguration entfernen. Diese Vorgehensweise stellt sicher, dass die neue Version fehlerfrei läuft, bevor Sie die alte deaktivieren.
Listing 2: Einen Server auf AWS einrichten
resource "aws_instance" "blue" {
  ami       = "ami-0c55b159cbfafe1f0"
  instance_type = "t2.micro"
  subnet_id   = aws_subnet.main.id
  security_groups = [aws_security_group.main.name]
  tags = {
    Name = "blue-green-app-blue"
  }
  // ... Andere Konfigurationen
}
resource "aws_elb" "main" {
  name      = "blue-green-app-elb"
  // ... Andere Konfigurationen
  instances = [aws_instance.blue.id]
}
```
Listing 3: Weitere Ressourcen in AWS bereitstellen
resource "aws_instance" "green" {
  ami       = "ami-0c55b159cbfafe1f0"
  instance_type = "t2.micro"
  subnet_id   = aws_subnet.main.id
  security_groups = [aws_security_group.main.name]
  tags = {
    Name = "blue-green-app-green"
  }
  // ... Andere Konfigurationen
}
```
Fazit
Zero-Downtime-Deployments sind nahezu unerlässlich, um kontinuierliche Verfügbarkeit und Servicequalität zu gewährleisten. Durch den Einsatz von Strategien wie Rolling Updates und Blue-Green-Deployments können Sie Systeme effizient und ohne Unterbrechungen aktualisieren. Terraform bietet dabei als Werkzeug zur Verwaltung von Infrastruktur als Code die nötige Flexibilität und Kontrolle, um ZDD sicher und konsistent umzusetzen.
Erfolgreiche ZDD mit Terraform erfordern sorgfältige Planung und eine klare Strategie. Sie sollten die spezifischen Anforderungen Ihrer Infrastruktur und Anwendungen berücksichtigen und sicherstellen, dass alle beteiligten Komponenten und Prozesse aufeinander abgestimmt sind. Mit den richtigen Tools und Best Practices erreichen Sie dann nahtlose Deployments, die sowohl die Betriebszeit maximieren als auch die Benutzererfahrung verbessern.
(jp)