Die Möglichkeit, Infrastruktur automatisiert über Code oder Konfiguration bereitzustellen, nennt man Infrastructure as Code oder kurz: IaC.
IaC ist aus der IT nicht mehr wegzudenken und ein effizienter Betrieb von SW in der Cloud ist ohne IaC kaum mehr möglich.
Durch die Möglichkeit, seine Infrastruktur schnell und immer wieder identisch aufzubauen, können Standards in gleichbleibend hoher Qualität durchgesetzt werden.
Terraform ist ein beliebtes und weit verbreitetes Werkzeug in diesem Bereich. HashiCorp, die Firma hinter Terraform, hat erst kürzlich die Lizenz von Terraform geändert. Statt der bisher offenen „Mozilla Public License 2.0 (MPL 2.0)“ kommt nun die eher geschlossene „Business Source License (BSL) 1.1“, damit entfernt Terraform sich damit vom klassischen OpenSource-Ansatz.
Pulumi ist ein weiterer Akteur, der einen etwas anderen Ansatz als Terraform verfolgt.
Wie funktioniert Terraform?
Terraform verwendet eine proprietäre Konfigurationssprache namens HCL (HashiCorp Configuration Language).
Um die benötigten Ressourcen zu erstellen, verwendet Terraform eine offizielle API des jeweiligen Cloud-Anbieters (Azure, GCP, AWS, …). Dabei merkt sich Terraform die bereits erstellten Objekte und kann bei einer erneuten Ausführung erkennen, ob und welche Anpassungen vorgenommen werden müssen.
Folgendes Beispiel erstellt eine VM auf Azure:
resource "azurerm_linux_virtual_machine" "myLinuxVM" { name = "myLinuxVM" location = azurerm_resource_group.myResourceGroup.location resource_group_name = azurerm_resource_group.myResourceGroup.name size = "Standard_DS1_v2" admin_username = "adminuser" admin_password = "Password1234!" source_image_reference { publisher = "Canonical" offer = "UbuntuServer" sku = "18.04-LTS" version = "latest" } } # Export the public IP address of the VM output "public_ip_address" { value = azurerm_public_ip.myPublicIp.ip_address }
Was ist Pulumi?
Pulumi funktioniert im Prinzip genauso wie Terraform. Auch Pulumi benutzt die offiziellen APIs der verschiedenen Anbieter um die definierten Ressourcen zu erstellen.
Ebenso merkt sich Pulumi den Zustand des Deployments und verwendet diesen, um zu ermitteln, welche Anpassungen bei einer erneuten Ausführung vorgenommen werden müssen.
Im Gegensatz zu Terraform basiert Pulumi aber nicht auf einer eigenen Konfigurationssprache, sondern erlaubt dem Benutzer zwischen verschiedenen Programmiersprachen zu wählen.
Derzeit unterstützt Pulumi die folgenden Sprachen: TypeScript, JavaScript, Python, Go, C#, Java, YAML.
Zusätzlich besteht die Möglichkeit, Code aus anderen proprietären Formaten zu konvertieren.
So können Terraform HCL, AWS CloudFormation Templates, Azure Resource Manager Templates und Kubernetes YAML in Pulumi übersetzt werden.
const linuxVm = new azureNative.compute.LinuxVirtualMachine("myLinuxVM", { resourceGroupName: resourceGroup.name, location: resourceGroup.location, osProfile: { adminUsername: "adminuser", adminPassword: "Password1234!", }, hardwareProfile: { vmSize: "Standard_DS1_v2", }, storageProfile: { imageReference: { publisher: "Canonical", offer: "UbuntuServer", sku: "18.04-LTS", version: "latest", }, }, }); // Export the public IP address of the VM export const publicIpAddress = publicIp.ipAddress;
Pulumi vs. Terraform
Die Tatsache, dass Terraform keine echte Programmiersprache, sondern eine proprietäre Konfigurationssprache verwendet, hat einige Konsequenzen, die oft erst bewusst werden, wenn man mit bestimmten Herausforderungen konfrontiert wird. Zum Beispiel ist es mit einer echten Programmiersprache sehr einfach, einfache Datenmanipulationen oder Iterationen durchzuführen.
Mit Terraform gibt es dafür meistens eine Lösung, die sich aber oft wie ein „Workaround“ anfühlt.
Ein Beispiel: Erstellung einer Anzahl von VMs, basierend auf einer Liste von Namen.
Wenn man sich mal mit HCL auseinander gesetzt hat, ist dies kein grosses Problem, aber es fühlt sich doch sehr speziell an:
variable "vm_names" { description = "List of VM names to create" type = list(string) default = ["vm1", "vm2", "vm3"] } resource "azurerm_linux_virtual_machine" "myVMs" { count = length(var.vm_names) name = var.vm_names[count.index] location = azurerm_resource_group.myResourceGroup.location resource_group_name = azurerm_resource_group.myResourceGroup.name ... }
Mit Pulumi ist dies eine einfache Schleife je nach Sprache die eingesetzt wird, hier TypeScript:
// List of VM names to create var vmNames = ["vm1", "vm2", "vm3"]; vmNames.forEach((vmName, index) => { new azure.compute.VirtualMachine(vmName, { resourceGroupName: resourceGroup.name, location: resourceGroup.location, ... } }
Die Verwendung einer Programmiersprache erlaubt es zudem, auf bestehende Bibliotheken und Frameworks zurückzugreifen oder weitergehende Ansätze umzusetzen. So kann Pulumi beispielsweise einfach in eine bestehende Anwendung integriert werden.
Terraform ist sehr viel bekannter als Pulumi und das Ökosystem ist sehr gross (https://registry.terraform.io/). Auf der anderen Seite wächst der Katalog von Pulumi ständig und lässt kaum etwas vermissen (https://www.pulumi.com/registry/).
Bemerkenswert ist auch, wie Pulumi mit Updates auf der Providerseite umgeht.
Der Grossteil des Codes wird automatisch aus den API-Spezifikationen der Anbieter generiert.
Im Falle von Azure bedeutet dies beispielsweise, dass innerhalb weniger Stunden, nachdem Microsoft eine neue Funktion über seine API veröffentlicht hat, diese auch in Pulumi zur Verfügung steht.
Was ist besser?
Grundsätzlich sind beide Tools erprobt und erfüllen ihren Zweck. Terraform ist weit verbreitet, hat aber mit dem Ansatz einer starren Konfigurationssprache gewisse Grenzen und man hat schnell das Gefühl, immer wieder auf Copy/Paste zurückgreifen zu müssen – diese Grenzen versucht Pulumi durch den Einsatz bekannter Programmiersprachen zu durchbrechen. Letztendlich muss aber jeder für sich selbst eine Bewertung vornehmen und entscheiden.
Neben dem reinen „Doing“ sind aber auch folgende Punkte zu beachten:
- Als Reaktion auf die Lizenzanpassung von Terraform wurde ein neues OpenSource-Projekt ins Leben gerufen: OpenTofu.
- Auch hinter Pulumi steht eine Firma, diese trägt den gleichen Namen: Pulumi.
- Pulumi wird unter der offenen „Apache License 2.0“ veröffentlicht und erfüllt damit die Anforderungen der Open Source Initiative (OSI).