Essenzielle Grundlage für Cloud DevOps
Das DevOps-Arbeitsmodell und Methodiken steigern die Qualität und beschleunigen die Entwicklung eines Produkts. Wichtige Bestandteile von DevOps sind Versionsverwaltung von Code (oder GitOps) und CI/CD Pipeline zum automatisierten Testen und produktiven Bereitstellen neuer Features.
Durch Angebote von Cloud Providern in den Bereichen Infrastructure‑, Plattform- und Software-as-a-Service kann die grundliegende Infrastruktur schnell und beinah unbegrenzt provisioniert werden. Viele Cloud Provider erlauben es, Infrastruktur als Code (IaC) zu definieren und somit kann nun auch die erforderliche Infrastruktur in die Versionsverwaltung und automatischen CI/CD Prozesse inkludiert werden. IaC in der Kombination mit DevOps bringt mehrere bedeutsame Vorteile für Infrastruktur in den folgenden Punkten:
- Versionierung und Wiederverwendung
- Schnelle Bereitstellung und Anpassung
- Automatisierte Tests
- Vermeidung von manuellen Konfigurationsfehlern
IaC Tools im Vergleich
IaC kann mit verschiedenen Tools realisiert werden. Dabei ist es wichtig, zwischen der Provisionierung von Infrastruktur und dem Bereitstellen und der Konfiguration von Software und Applikationen zu unterscheiden. Entsprechend lassen sich die Tools je nach ihrem Schwerpunkt in zwei Kategorien unterteilen (siehe Bild). Viele IaC Tools können schwerpunktübergreifend eingesetzt und, wenn dies nicht möglich oder optimal ist, mit den anderen Tools kombiniert werden. Der Fokus des aktuellen Blogbeitrags liegt vor allem auf der Provisionierung von Cloud Infrastrukturen; daher wird die andere Kategorie nicht näher betrachtet.
Vendor Lock-in
Die Wahl der IaC-Technologie ist von verschiedenen Faktoren abhängig. Einer der wichtigsten Punkte dabei ist die Vermeidung von Vendor-Lock-In. Unter Vendor-Lock-In versteht man eine so starke Abhängigkeit von den Produkten eines Anbieters, dass ein Wechsel des Anbieters unverhältnismäßig aufwändig wird. In Bezug auf IaC bedeutet dies, eine Technologie zu nutzen, die auf verschiedenen Cloud Plattformen anwendbar ist.
Cloud Templates wie AWS CloudFormation, Google Deployment Manager und Azure Resource Manager mit dem Nachfolger Bicep decken nur Ressourcen in ihren eigenen Cloud Umgebungen ab. Dagegen unterstützen die Tools wie Terraform und Pulumi den Multi-Cloud Ansatz und können Ressourcen plattformübergreifend provisionieren. Es ist zu beachten, dass ein mit Terraform oder Pulumi geschriebener Code für die Infrastruktur auf einer Cloud Plattform nicht direkt auf andere Cloud Plattformen übertragbar ist, sondern erfordert eine gewisse Migration oder Anpassung. Der Grund dafür sind mangelnde standardisierte Schnittstellen von Cloud Services.
Der Vorteil von Terraform oder Pulumi im Vergleich zu den plattformnativen Tools besteht darin, dass der Entwickler prinzipiell nur ein einzelnes Werkzeug beherrschen muss, um verschiedene Cloud Plattformen zu bedienen, statt für jede Cloud-Plattform eine neue IaC Sprache lernen zu müssen. Die Cloud Templates lohnen sich hauptsächlich dann, wenn neue Cloud Provider Features nach ihrem Release ohne Verzug eigesetzt werden sollen, denn Terraform und Pulumi brauchen dafür zusätzliche Implementierungszeit. Alternativ können Cloud Templates aber auch mit Terraform oder Pulumi ausgerollt werden.
Integration
Der zweite entscheidende Faktor für ein IaC Tool sind Funktionsumfang und Integration mit anderen Software-Lösungen. Wie bereits erwähnt beschränken sich die Cloud Templates von AWS, GCP und Azure sich lediglich auf Ihre eigenen Services und erlauben keine Integration mit anderen Plattformen. Im Gegensatz dazu unterstützen Terraform und Pulumi nicht nur die drei größten Cloud Anbieter AWS, Azure und GCP, sondern auch zahlreiche andere Produkte. Zu den letzten gehören unter anderem solche Provider wie Snowflake, Kubernetes, VMware und Oracle Cloud. Dabei ist zu beachten, dass Terraform deutlich mehr andere Technologien unterstützt als Pulumi, obwohl Pulumi sicherlich eine gute Alternative zu Terraform bei den wichtigsten Providern darstellt.
Umfang und Reifegrad
Schließlich unterscheiden sich die IaC Tools im Umfang und Reifegrad der Features. Dazu gehören vor allem die unterstützten Programmiersprachen. Native Cloud Templates und Terraform haben ihre eigenen Skriptsprachen. Die Sprachen sind zwar gut dokumentiert und erlauben einen schnellen Einstieg, die Benutzung von komplexeren Sprachfunktionalitäten erfordert jedoch Praxiserfahrung und tiefes Verständnis des jeweiligen Tools. Zusätzlich bieten Terraform und die größten Cloud Plattformen wie AWS, Azure und Google ein Service oder Cloud Development Kit (SDK/CDK), um den Code in anderen Sprachen wie Python, C#, Go, Typescript, Java, Javascript oder .NET zu schreiben. Pulumi besitzt keine eigene Sprache und verwendet Python, Go, JavaScript, TypeScript, C# und Java. Durch die gängigen Skriptsprachen bekommt der Entwickler den Zugang zu vertrauten Konstrukten und Techniken inkl. Testing.
Weitere Anforderungen an Sprachfeatures sind:
- dynamische Provisionierung von Ressourcen, wenn die Anzahl von Ressourcen und Ihre Konfiguration erst zur Laufzeit des Skripts bekannt werden;
- benutzerdefinierte Validierung von Parametern und Ressourcen vor und nach dem Bereitstellen;
- Definition von Update- und Delete-Verhalten von Ressourcen.
Terraform und Pulumi können solche Szenarien Out-of-the-Box implementieren. Cloud Templates lassen das aber ohne eine Erweiterung mit SDK/CDK nur sehr begrenzt zu.
Die wichtigsten Punkte aus der Übersicht von IaC Tools sind:
- Die meisten Cloud-Projekte sind technologie- und plattformübergreifend;
- Vendor Lock-In kann mit Terraform oder Pulumi vermieden werden;
- Plattformnative Cloud Templates, Terraform und Pulumi erlauben eigene oder weiterverbreitete Skriptsprachen (Python, Java, C#, JavaScript, usw.) zu nutzen;
- Terraform kann mit deutlich mehr anderen Technologien integriert werden als alle anderen IaC Tools.
Es lässt sich zusammenfassend festhalten, dass Cloud Infrastrukturen aktuell optimalerweise mit Terraform oder Pulumi umgesetzt werden können. Im nächsten Kapitel wird im Detail auf Anwendung von Terraform eingegangen; ein Vergleich mit Pulumi erfolgt im Schlusskapitel.
Terraform: High-Level Übersicht und Best Practices
HashiCorp Language
IaC Skripte mit Terraform werden anhand der domänenspezifischen Sprache HashiCorp Language (HCL) verfasst. HCL ist eine deklarative menschenlesbare und leicht erlernbare Sprache. HCL implementiert zahlreiche Grundfunktionalitäten wie For-Schleifen, If-Bedingungen und umfangreiche Built-in Funktionen. Die Ausführung von Terraform Skripten erfolgt mit der Open Source CLI terraform.
Provider
Terraform verfügt über ein Registry, in dem sogenannte Terraform Provider für verschiedene Cloud Plattformen und Services kostenlos angeboten werden. Ein Provider ist eine Bibliothek von Modulen zum Erstellen von Ressourcen, die in Terraform Skripten angebunden werden können. Terraform Skripte bestehen im Wesentlichen aus Aufrufen von solchen bereitgestellten Modulen und deren Abhängigkeiten. Daraus resultieren Module für ein eigenes Produkt oder Infrastruktur.
Parameter
Die Skripte lassen sich wiederverwenden, indem Eingabeparameter deklariert werden. Die Eingabeparameter können zusätzlich mit Custom Condition Checks validiert werden, was z.B. bei Verwendungen von Terraform im Self-Service Bereich sinnvoll eingesetzt werden kann. Die Eingabeparameter für einen konkreten Fall können dann z.B. über .tfvars-Dateien bei der Ausführung mitgegeben werden. Die Terraform Skripte spielen in dem Fall die Rolle von Templates und die .tfvars-Dateien sind entsprechende Konfigurationsdateien. Es empfiehlt sich, die Templates und die Konfigurationsfiles separat zu versionieren, wobei die Konfiguration eine Release-Version von den Templates enthalten soll. Die Versionierung von den Template Skripten z.B. durch Tags ermöglicht die Wiederverwendung dieser Template Module in einem anderen Terraform Code, denn Terraform erlaubt Module direkt aus einem Git-Repository zu referenzieren.
State-Datei
Der andere Bestandteil von Terraform, abgesehen von Skripten, ist Terraform’s .tfstate-Datei. Die Datei gehört zu jedem Terraform Projekt und mappt die Ressourcen aus den Skripten und Konfiguration auf die reale Welt. Die .tfstate-Datei ist ein JSON File und speichert Ressourcenattribute, ‑metadaten und ‑abhängigkeiten. Per Default aktualisiert Terraform die gecachten Attribute für alle Ressourcen in der State-Datei bei jeder Ausführung. Für große Cloud-Infrastrukturen führt dies zur Minderung der Performanz. Um die Performanz für große Workloads aufrecht zu erhalten, empfiehlt Terraform die Verwendung von den Flags –refresh=false und –target.
Die State-Datei sollte auch in die Versionskontrolle inkludiert werden, allerdings ist Git nicht immer sinnvoll dafür, da die Datei sensible Daten (z.B. Passwörter) im Klartext enthalten kann. Ein einfaches Beispiel dafür ist: Generieren eines Passworts und Speichern als Azure Key Vault Secret. Sowohl das Passwort als auch der Secret werden in der .tfstate-Datei ohne Verschlüsselung geschrieben. Als Lösung bietet Terraform Remote Backends als Speichertort für .tfstate-Dateien. Dazu gehören z.B. Azure Storage, AWS S3, und Artifactory. Der Zugang zum Remote Backend sollte durch Zugriffskontrolle stark eingeschränkt werden.
Testing
Zu Entwicklungsarbeiten mit Terraform gehört auch das Thema Software Testing. Integration- und Unittests können mit den nativen Terraform Befehlen „validate“, „plan“ und „apply“ durchgeführt werden. Die Ausführung durch Terraform erfolgt in zwei Schritten. Als erstes wird der Code validiert und ein Terraform Plan generiert, der beschreibt, welche Abweichungen es zwischen der Terraform Konfiguration und den realen Ressourcen gibt, und, wie Terraform die Unterschiede beheben würde. Wenn der Plan stimmig ist, dann kann der Plan mit Terraform Apply angewendet werden und die Ressourcen werden entsprechend dem Plan angepasst. Zwischen den Validate, Plan und Apply Befehlen können Prüfungschecks erfolgen, um die erforderliche Qualität des Codes sicherzustellen.
Compliance Testing ist möglich mit dem Open Source terraform-compliance Tool. Das Tool erlaubt es, eigene Policies (z.B. Unterbinden von Azure Storage Account mit Public Access) für Terraform Code zu definieren und den Code dagegen zu prüfen. Im Hinblick auf End-to-End (E2E) Tests empfiehlt sich Terratest, eine Go Bibliothek zum Implementieren von automatisierten Tests für Terraform. Schließlich ergibt sich die folgende DevOps-Architektur für Terraform:
Zusammenfassung: welches Tool soll bevorzugt werden?
Der Schwerpunkt des aktuellen Blogartikels liegt auf Provisionierung von Infrastrukturen, und zwar mit Terraform. Es gibt momentan kein IaC Tool, das alle Bedürfnisse abdeckt. So haben auch Terraform und Pulumi ihre Schwierigkeiten bei der Konfiguration und Verwaltung von bereits provisionierten Servern, im Gegensatz zu Ansible oder Puppet. Terraform und Pulumi zeigen deutlich mehr Stärken durch Multi-Cloud Fähigkeit und Integration mit anderen Technologien gegenüber nativen Cloud Templates vom Azure, AWS oder GCP. Die wichtigsten Unterschiede zwischen Terraform und Pulumi sind:
- Provider: Terraform unterstützt aktuell deutlich mehr Provider als Pulumi
- Secrets in State-Datei: Pulumi verschlüsselt Secrets in der State-Datei im Gegensatz zu Terraform.
- API: Im Vergleich zu Terraform kann Pulumi kann nur über CLI, sondern auch über eine API direkt aus dem Programmcode aufgerufen werden.
- Refactoring: Pulumi erlaubt mithilfe von Aliases eine simplere Überarbeitung und Verschiebung von Ressourcen innerhalb des Codes als Terraform.
Da Terraform und Pulumi gegenseitig sowohl Vor- als auch Nachteile haben, bleibt die Wahl zwischen den beiden projektspezifisch.