Wer Cloud-Infrastruktur heute noch manuell über Web-Konsolen zusammenklickt, zahlt dafür mit Inkonsistenzen, fehlender Nachvollziehbarkeit und langsamen Deployments. Infrastructure as Code (IaC) hat sich als Standard etabliert, um Infrastruktur reproduzierbar, versioniert und testbar zu verwalten. Zwei Tools dominieren den Markt: Terraform von HashiCorp und Pulumi. Beide verfolgen das gleiche Ziel, gehen aber grundlegend unterschiedliche Wege dorthin.
Dieser Artikel vergleicht beide Werkzeuge anhand konkreter Kriterien und liefert eine Entscheidungshilfe, die über oberflächliche Feature-Listen hinausgeht.
Sprachmodell: HCL vs. echte Programmiersprachen
Der offensichtlichste Unterschied: Terraform nutzt die eigene Konfigurationssprache HCL (HashiCorp Configuration Language), Pulumi setzt auf gängige Programmiersprachen wie TypeScript, Python, Go oder C#.
HCL ist deklarativ und absichtlich eingeschränkt. Das klingt nach einer Limitierung, ist in der Praxis aber eine Stärke: Terraform-Konfigurationen sind auch für Team-Mitglieder lesbar, die kein tiefes Programmier-Know-how mitbringen. Ops-Engineers, die aus der Infrastruktur-Ecke kommen, finden sich schnell zurecht.
resource "aws_s3_bucket" "data_lake" {
bucket = "everbright-data-lake-prod"
tags = {
Environment = "production"
ManagedBy = "terraform"
}
}
resource "aws_s3_bucket_versioning" "data_lake" {
bucket = aws_s3_bucket.data_lake.id
versioning_configuration {
status = "Enabled"
}
}
Pulumi drückt dieselbe Infrastruktur in TypeScript aus:
import * as aws from "@pulumi/aws";
const dataLake = new aws.s3.Bucket("data-lake", {
bucket: "everbright-data-lake-prod",
tags: {
Environment: "production",
ManagedBy: "pulumi",
},
});
const versioning = new aws.s3.BucketVersioningV2("data-lake-versioning", {
bucket: dataLake.id,
versioningConfiguration: {
status: "Enabled",
},
});
Der Pulumi-Ansatz spielt seine Stärke aus, wenn komplexe Logik ins Spiel kommt. Schleifen, Bedingungen, Abstraktionen mit Klassen und Funktionen, Type Safety durch den Compiler. Wer bereits ein DevOps-Team mit Software-Engineering-Hintergrund hat, profitiert davon. Wer dagegen ein reines Ops-Team hat, das bisher mit Ansible oder Shell-Skripten gearbeitet hat, fährt mit HCL oft besser.
State Management: Wer merkt sich den Zustand?
Beide Tools arbeiten mit einem State, der den aktuellen Zustand der verwalteten Infrastruktur abbildet. Terraform speichert diesen State standardmäßig lokal als JSON-Datei. Für Teams ist ein Remote Backend Pflicht, typischerweise S3 + DynamoDB (Locking) oder Terraform Cloud.
terraform {
backend "s3" {
bucket = "everbright-tf-state"
key = "prod/infrastructure.tfstate"
region = "eu-central-1"
dynamodb_table = "terraform-locks"
encrypt = true
}
}
Pulumi bietet einen Managed Service (app.pulumi.com) als Default, der State, Locking und Verschlüsselung out of the box mitbringt. Alternativ lässt sich der State auch in S3, Azure Blob oder lokal speichern. Der Managed Service funktioniert gut, bedeutet aber eine zusätzliche Abhängigkeit von Pulumi als Anbieter.
Für regulierte Umgebungen, in denen Daten das Unternehmen nicht verlassen dürfen, ist Terraform mit einem selbst verwalteten Backend die flexiblere Wahl. Pulumi bietet mit dem Self-Hosted Backend ebenfalls eine Lösung, die ist aber weniger erprobt als das Terraform-Pendant.
Testing: Infrastruktur absichern
Einer der Bereiche, in denen Pulumi konzeptionell vorn liegt. Da Pulumi-Programme normale Code-Dateien sind, lassen sich Unit Tests mit dem jeweiligen Test-Framework der Sprache schreiben:
import * as pulumi from "@pulumi/pulumi";
import { describe, it, expect } from "vitest";
// Mock-Setup für Pulumi
pulumi.runtime.setMocks({
newResource: (args) => ({ id: `${args.name}-id`, state: args.inputs }),
call: () => ({}),
});
describe("S3 Bucket", () => {
it("should have versioning enabled", async () => {
const infra = await import("../index");
const bucket = infra.dataLake;
const tags = await new Promise<Record<string, string>>((resolve) =>
bucket.tags.apply((t) => resolve(t ?? {}))
);
expect(tags.ManagedBy).toBe("pulumi");
});
});
Terraform bietet mit terraform validate und terraform plan grundlegende Prüfungen. Für echte Tests gibt es Terratest (Go-basiert) oder das neuere Terraform Testing Framework mit .tftest.hcl-Dateien. Die Einstiegshürde ist höher, dafür existiert ein ausgereiftes Ökosystem an Modulen und Patterns.
Wer bereits CI/CD-Pipelines mit Test-Stages betreibt, wird Pulumis nativen Test-Ansatz schätzen. Wer Infrastruktur primär über Reviews und plan-Outputs absichert, kommt mit Terraform gut zurecht.
Multi-Cloud und Provider-Ökosystem
Terraform hat hier den klaren Vorteil der Masse: Über 4.000 Provider in der Registry, von AWS über Azure und GCP bis zu Cloudflare, Datadog und Kubernetes. Die Community-Beiträge sind riesig, die Dokumentation ist umfangreich, und für fast jeden Cloud-Service existiert ein ausgereifter Provider.
Pulumi bietet ebenfalls Provider für alle großen Cloud-Plattformen und kann zusätzlich Terraform-Provider als sogenannte Bridged Providers nutzen. In der Praxis funktioniert das meistens, es gibt aber gelegentlich Verzögerungen bei neuen Features oder Inkompatibilitäten bei Edge Cases.
Für Multi-Cloud-Setups mit AWS, Azure und On-Premises ist Terraform das bewährtere Werkzeug. Nicht weil Pulumi es nicht kann, sondern weil die Terraform-Module in Produktion umfangreicher getestet sind und mehr Battle-Tested-Patterns existieren.
Module und Wiederverwendbarkeit
Terraform setzt auf Module als Abstraktionsmechanismus. Ein Modul ist ein Verzeichnis mit .tf-Dateien, das über Variablen parametrisiert wird. Die Terraform Registry enthält Tausende fertiger Module, etwa für VPC-Setups, EKS-Cluster oder RDS-Instanzen.
module "vpc" {
source = "terraform-aws-modules/vpc/aws"
version = "5.5.0"
name = "everbright-prod"
cidr = "10.0.0.0/16"
azs = ["eu-central-1a", "eu-central-1b"]
private_subnets = ["10.0.1.0/24", "10.0.2.0/24"]
public_subnets = ["10.0.101.0/24", "10.0.102.0/24"]
enable_nat_gateway = true
single_nat_gateway = true
}
Pulumi nutzt Component Resources, also Klassen, die mehrere Ressourcen bündeln. Da es sich um echten Code handelt, können diese über npm, PyPI oder andere Paketmanager verteilt werden. Das ermöglicht elegante Abstraktionen:
class EverBrightVpc extends pulumi.ComponentResource {
public readonly vpcId: pulumi.Output<string>;
constructor(name: string, args: VpcArgs, opts?: pulumi.ComponentResourceOptions) {
super("everbright:network:Vpc", name, {}, opts);
const vpc = new aws.ec2.Vpc(`${name}-vpc`, {
cidrBlock: args.cidr,
tags: { Name: name, ManagedBy: "pulumi" },
}, { parent: this });
this.vpcId = vpc.id;
this.registerOutputs({ vpcId: this.vpcId });
}
}
Beide Ansätze funktionieren. Terraforms Modul-System ist simpler und besser dokumentiert. Pulumis Klassen-Ansatz ist mächtiger, verlangt aber Software-Engineering-Disziplin, damit die Abstraktionen nicht ausufern.
Entscheidungshilfe: Wann welches Tool?
Die Wahl zwischen Terraform und Pulumi ist keine Frage von “besser oder schlechter”, sondern von Team-Kontext und Anforderungen.
Terraform ist die richtige Wahl, wenn das Team primär aus Ops-Engineers besteht, ein großes Multi-Cloud-Setup verwaltet wird, oder die Organisation bereits Terraform-Module und -Workflows etabliert hat. Die riesige Community, die ausgereifte Registry und die breite Tooling-Unterstützung (Atlantis, Spacelift, env0) machen Terraform zum sicheren Standard.
Pulumi passt besser, wenn das Infrastruktur-Team einen starken Software-Engineering-Hintergrund hat, Tests und Type Safety für Infrastruktur-Code Priorität haben, oder die Infrastruktur eng mit Applikationscode verzahnt ist. Gerade in TypeScript-lastigen Umgebungen, wo Backend, Frontend und Infrastruktur in derselben Sprache geschrieben werden, reduziert Pulumi den Kontextwechsel.
Für den Mittelstand, der gerade erst mit IaC startet, ist Terraform oft der pragmatischere Einstieg. Die Lernkurve ist flacher, die Dokumentation besser, und die Wahrscheinlichkeit, erfahrene Terraform-Entwickler am Markt zu finden, ist höher. Pulumi wird dann interessant, wenn das Team wächst und die Anforderungen an Testbarkeit und Abstraktion steigen.
Fazit
Infrastructure as Code ist kein Nice-to-have mehr, sondern Voraussetzung für reproduzierbare, auditierbare Cloud-Infrastruktur. Terraform bleibt der De-facto-Standard mit dem breitesten Ökosystem. Pulumi bietet die modernere Developer Experience, besonders für Teams, die Infrastruktur wie Software behandeln wollen.
Beide Tools lösen das gleiche Problem. Die Entscheidung hängt davon ab, wer im Team damit arbeitet und wie die bestehende Toolchain aussieht. Wer unsicher ist, startet mit einem kleinen Proof of Concept für beide Varianten und trifft die Entscheidung anhand echter Erfahrungswerte statt theoretischer Feature-Vergleiche.
EverBright IT unterstützt Cloud-Teams bei der Auswahl und Einführung von IaC-Werkzeugen, von der Strategie bis zur produktionsreifen Pipeline. Mehr zu unseren Cloud-Services oder direkt Kontakt aufnehmen →
Häufige Fragen
Ist Terraform oder Pulumi besser für Anfänger?
Terraform hat die flachere Lernkurve. HCL ist einfacher als Programmiersprachen, die Dokumentation umfangreicher, und die Community größer. Pulumi ist besser, wenn das Team bereits TypeScript oder Python kennt.
Wie viele Provider hat Terraform?
Über 4000 Provider in der Registry, von großen Cloud-Plattformen bis zu spezialisierten Services wie Datadog oder Cloudflare. Pulumi nutzt ebenfalls diese Provider und kann zusätzlich Terraform-Provider als Bridged Providers integrieren, mit gelegentlichen Verzögerungen bei neuen Features.
Kann man Terraform State selbst verwalten?
Ja, mit einem Remote Backend wie S3 plus DynamoDB für Locking. Das ist für regulierte Umgebungen oft Anforderung. Pulumi bietet einen Managed Service oder Self-Hosted Backend, das Self-Hosted Backend ist aber weniger erprobt.
Wie testet man Infrastruktur mit Terraform?
Mit terraform validate und terraform plan für Basis-Checks, Terratest oder das Terraform Testing Framework für echte Unit Tests. Pulumi-Programme können mit dem Native Test-Framework der Sprache getestet werden, was eleganter ist aber höhere Setup-Anforderungen hat.