Claude Code & Pulumi: Infrastructure as Code mit echten Programmiersprachen

Infrastructure as Code war lange gleichbedeutend mit einer eigenen Sprache lernen: HCL für Terraform, YAML für CloudFormation, JSON für ARM-Templates. Das war kein Zufall — die DSL-Philosophie hatte Vorteile: deklarativ, prüfbar, versionierbar. Aber sie hatte auch einen grundlegenden Nachteil: Schleifen, Variablen, Bedingungen, Modularisierung fühlten sich immer wie nachträgliche Behelfslösungen an.

Pulumi geht einen anderen Weg. Infrastruktur wird in echten Programmiersprachen definiert — TypeScript, Python, Go, C#. Was Terraform per count-Hack ausdrückt, ist in Pulumi eine normale for-Schleife. Was HCL als Template-Funktion umständlich löst, ist TypeScript-Logik. Und Claude Code beschleunigt diesen Workflow erheblich: nicht nur beim Schreiben der Infrastruktur, sondern beim Verstehen vorhandener Stacks, beim Debuggen von Provider-Fehlern und beim Strukturieren von Multi-Environment-Setups.

Claude Code Mastery — IaC, Agents, Workflows auf Deutsch

Pulumi ist eine von vielen Integrationen, die Claude Code beherrschbar machen. Der Kurs zeigt vollständige Workflows — von der Infrastruktur bis zum Deploy. Einmalig bezahlt, kein Abo.

Zum Kurs — Jetzt starten → Einmalzahlung · Kein Abo · 14 Tage Rückgaberecht

1. Pulumi vs. Terraform: Der entscheidende Unterschied

Terraform ist Marktführer im IaC-Bereich — das ist nicht zu leugnen. HCL ist lesbar, das Provider-Ökosystem ist riesig, und die Community ist groß. Aber wer komplexere Infrastruktur verwaltet, stößt schnell an Grenzen: bedingte Ressourcen, dynamische Blöcke, wiederverwendbare Module mit Typ-Prüfung, Loops über heterogene Listen. Das alles ist in HCL möglich, aber umständlich.

Pulumi löst genau das: Infrastruktur ist Code, nicht Konfiguration. Wer TypeScript kennt, schreibt Infrastruktur mit denselben Werkzeugen, die er für seine Applikation benutzt. Dasselbe Lint-Setup, dieselben Tests, derselbe IDE-Support inklusive Auto-Vervollständigung und Typ-Prüfung. Das ist kein kosmetischer Unterschied — es hat direkte Auswirkungen darauf, wie schnell man Fehler findet und wie gut sich Infrastruktur in Teams skalieren lässt.

Der Wechsel von Terraform zu Pulumi ist kein Paradigmenwechsel — es ist eher eine Rückkehr zur normalen Softwareentwicklung. Und Claude Code unterstützt diesen Workflow, weil es TypeScript und Python nativ versteht: keine separate Sprache, kein spezialisiertes Training notwendig.

2. Ein Pulumi-Stack mit Claude Code erstellen

Der Einstieg ist schnell. Ein neues TypeScript-Projekt lässt sich mit Claude Code so initialisieren:

claude "Erstelle ein Pulumi-TypeScript-Projekt für eine AWS Lambda-Funktion
mit API Gateway. Verwende @pulumi/aws und @pulumi/awsx. Die Lambda soll
aus einem lokalen dist/-Verzeichnis deployed werden."

Claude Code liest die vorhandene Projektstruktur, erkennt ob package.json vorhanden ist, und generiert ein vollständiges index.ts inklusive Pulumi.yaml und korrekter Provider-Konfiguration. Was dabei entsteht, ist kein generisches Beispiel — es ist an die tatsächliche Verzeichnisstruktur angepasst.

import * as aws from "@pulumi/aws";
import * as awsx from "@pulumi/awsx";

// Lambda-Funktion aus lokalem Build-Artefakt
const lambdaRole = new aws.iam.Role("lambdaRole", {
  assumeRolePolicy: aws.iam.assumeRolePolicyForPrincipal({
    Service: "lambda.amazonaws.com",
  }),
});

new aws.iam.RolePolicyAttachment("lambdaBasic", {
  role: lambdaRole.name,
  policyArn: aws.iam.ManagedPolicy.AWSLambdaBasicExecutionRole,
});

const lambda = new aws.lambda.Function("apiHandler", {
  runtime: aws.lambda.Runtime.NodeJS20dX,
  code: new pulumi.asset.FileArchive("./dist"),
  handler: "index.handler",
  role: lambdaRole.arn,
  environment: {
    variables: {
      NODE_ENV: "production",
      // Secrets nie im Klartext: aus Pulumi Config lesen
      DB_URL: config.requireSecret("dbUrl"),
    },
  },
});

export const functionArn = lambda.arn;

Secrets in Pulumi: Sensible Werte gehören nie als Klartext in den Code. config.requireSecret("dbUrl") liest aus dem verschlüsselten Pulumi-State. Setzen per CLI: pulumi config set --secret dbUrl "..." — Pulumi verschlüsselt den Wert automatisch mit dem Stack-Schlüssel.

3. Stacks und Environments

Das Stack-Konzept ist einer der größten Vorteile von Pulumi. Ein Stack ist eine isolierte Instanz deiner Infrastruktur — dev, staging, prod sind separate Stacks mit eigener Konfiguration, eigenem State und eigenen Secrets. Kein Copy-Paste-Problem wie bei Terraform-Workspaces, bei denen man leicht denselben State mit zwei Environments teilt.

# Neuen Stack anlegen
pulumi stack init dev

# Stack-spezifische Konfiguration setzen
pulumi config set aws:region eu-central-1
pulumi config set --secret dbUrl "postgresql://..."

# Zu anderem Stack wechseln
pulumi stack select prod

Claude Code versteht das Stack-Konzept und kann beim Strukturieren von Multi-Environment-Setups helfen. Typische Aufgabe:

claude "Ich habe einen Pulumi-Stack für dev. Erkläre mir, wie ich
eine gemeinsame Basisstruktur für dev, staging und prod erstelle,
ohne Code zu duplizieren."

Die Antwort zeigt, wie man Stack-Konfiguration aus Pulumi.dev.yaml, Pulumi.prod.yaml liest und gemeinsame Ressourcen in separate Komponenten auslagert — in TypeScript einfach als normale Klassen oder Funktionen.

4. AWS, GCP und Azure: Provider-Logik mit Claude Code

Pulumi unterstützt alle großen Cloud-Provider mit tiefer Typ-Integration. Wer von AWS zu GCP wechselt oder Multi-Cloud aufbaut, muss nicht zwei DSLs lernen — er nutzt dieselbe TypeScript-Toolchain mit unterschiedlichen npm-Paketen.

Wo Claude Code besonders hilfreich ist: Provider-Dokumentation. Die Pulumi-Provider haben Hunderte von Ressourcentypen, jede mit eigenen Feldern und Abhängigkeiten. Statt in der Doku zu suchen:

claude "Ich möchte einen GCS-Bucket mit Lifecycle-Regel anlegen, die
Objekte nach 90 Tagen löscht. Zeig mir den Pulumi-Code mit @pulumi/gcp."
import * as gcp from "@pulumi/gcp";

const bucket = new gcp.storage.Bucket("archiveBucket", {
  location: "EU",
  lifecycleRules: [{
    action: { type: "Delete" },
    condition: { age: 90 },
  }],
  uniformBucketLevelAccess: true,
});

export const bucketName = bucket.name;

Claude Code generiert direkt validen Pulumi-Code mit dem richtigen Provider-Typ, nicht eine generische Beschreibung. Das spart die Zeit für das Nachschlagen in der Referenz-Doku.

5. Secrets-Management ohne Klartextwerte

Pulumi hat ein eingebautes Secrets-System, das besser ist als Umgebungsvariablen per Hand zu verwalten. Secrets werden im State verschlüsselt abgelegt — wer den State-File liest, sieht keine Klartextwerte.

const config = new pulumi.Config();

// Secret aus Pulumi-Config lesen (verschlüsselt im State)
const apiKey = config.requireSecret("stripeApiKey");

// Umgebungsvariable in der Lambda setzen — bleibt als Output-Secret markiert
const fn = new aws.lambda.Function("paymentHandler", {
  environment: {
    variables: {
      STRIPE_API_KEY: apiKey,
    },
  },
  // ...
});

Wichtig: Pulumi markiert Outputs, die aus Secrets abgeleitet werden, automatisch als geheim. Sie erscheinen in pulumi up-Ausgaben als [secret] und werden nie im Klartext geloggt. Trotzdem gilt: process.env.VAR für Werte, die zur Laufzeit (nicht zur Deploy-Zeit) bekannt werden — die Trennung zwischen Build- und Runtime-Secrets ist wichtig.

Für komplexere Anforderungen unterstützt Pulumi auch externe Secret-Stores: AWS Secrets Manager, Azure Key Vault, HashiCorp Vault. Claude Code hilft beim Einrichten der entsprechenden Provider-Konfiguration:

claude "Ich möchte meinen Pulumi-Stack so konfigurieren, dass Secrets
in AWS Secrets Manager gespeichert werden statt im Pulumi-Cloud-State.
Zeig mir die Konfiguration für den AWS KMS Secrets Provider."

6. State-Backend: Pulumi Cloud vs. Self-Hosted

Standardmäßig speichert Pulumi den State in der Pulumi Cloud — ein verwalteter Dienst mit History, Rollback und Team-Features. Für Teams, die keinen externen State-Dienst nutzen wollen, gibt es Alternativen: S3-Backend, Azure Blob Storage, GCS oder ein lokales Filesystem.

# S3 als State-Backend konfigurieren
pulumi login s3://mein-pulumi-state-bucket

# Lokales Filesystem (für Tests und CI ohne Cloud-Account)
pulumi login --local

Der Wechsel des Backends ist einmalig pro Projekt. Claude Code kann helfen, die Implikationen zu verstehen — etwa dass beim Wechsel von Pulumi Cloud zu S3 der bestehende State migriert werden muss, und wie das konkret geht.

7. CI/CD-Integration

Pulumi lässt sich sauber in GitHub Actions, GitLab CI oder Jenkins integrieren. Das Muster ist immer gleich: Credentials aus Environment-Variablen lesen, Stack auswählen, pulumi up --yes ausführen.

# .github/workflows/deploy.yml (Ausschnitt)
- name: Deploy Infrastructure
  uses: pulumi/actions@v5
  with:
    command: up
    stack-name: prod
    work-dir: ./infra
  env:
    PULUMI_ACCESS_TOKEN: ${{ secrets.PULUMI_ACCESS_TOKEN }}
    AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
    AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}

Claude Code generiert vollständige Workflow-Dateien inklusive Preview-Step für Pull Requests (damit Änderungen sichtbar sind, bevor sie gemergt werden) und Deploy-Step für den Merge in main. Ein Aufruf:

claude "Erstelle eine GitHub Actions Workflow-Datei für meinen Pulumi-Stack.
Bei PRs soll 'pulumi preview' laufen und das Ergebnis als PR-Kommentar
gepostet werden. Bei Merge in main soll 'pulumi up' laufen."

Das Ergebnis ist ein produktionsreifer Workflow — mit korrekten Permissions, Concurrency-Einstellungen und dem Pulumi GitHub Actions-Kommentar-Plugin.


Zwei verwandte Artikel, die auf diesem Thema aufbauen:


Claude Code Mastery — von IaC bis zum produktiven Agenten

Pulumi, GitHub Actions, MCP-Server, Hooks, Multi-Agent-Workflows — alles auf Deutsch, einmalig bezahlt. Kein Abo, keine Plattformabhängigkeit.

Jetzt starten → Einmalzahlung · Kein Abo · 14 Tage Rückgaberecht

Kurs · Claude Code Mastery

Von Infrastructure as Code zum produktiven AI-Agenten

Pulumi. GitHub Actions. MCP. Hooks. Multi-Agent-Workflows. Alles auf Deutsch, einmalig bezahlt — kein Abo, keine Plattformabhängigkeit.

Jetzt einsteigen → Kursübersicht ansehen →

Einmalzahlung · Kein Abo · 14 Tage Rückgaberecht