Terraform für STACKIT: Beispiele aus der Praxis

Kubernetes, PostgreSQL, Object Storage und DNS auf STACKIT deklarativ bereitstellen — mit dem offiziellen Terraform-Provider.

By Timo Bergen | June 24, 2025

Terraform für STACKIT: Beispiele aus der Praxis

STACKIT ist die Cloud-Plattform der Schwarz Gruppe — Rechenzentren in Deutschland, Betrieb nach deutschem Recht. Für Unternehmen mit Anforderungen an digitale Souveränität ist das ein Argument, das AWS und Azure schwer kontern können. Und weil es einen offiziellen Terraform-Provider gibt, lässt sich die Plattform genauso deklarativ betreiben wie die Hyperscaler.

Provider einrichten

Authentifiziert wird über einen Service-Account-Schlüssel. Der Schlüssel gehört nicht ins Repository — er kommt aus einer Umgebungsvariablen oder einem Secret-Store.

terraform {
  required_version = "~> 1.9"

  required_providers {
    stackit = {
      source  = "stackitcloud/stackit"
      version = "~> 0.60"
    }
  }
}

provider "stackit" {
  default_region = "eu01"
  # Schlüssel via STACKIT_SERVICE_ACCOUNT_KEY_PATH
  # oder STACKIT_SERVICE_ACCOUNT_TOKEN
}

variable "project_id" {
  type        = string
  description = "STACKIT Projekt-ID (UUID aus dem Portal)."
}

Ein Hinweis vorab: Der Provider ist noch in der 0.x-Reihe und entwickelt sich schnell. Pinnen Sie die Version und gleichen Sie die Attributnamen mit der Provider-Dokumentation zur eingesetzten Version ab — die Beispiele hier zeigen die Struktur, nicht den unveränderlichen Wortlaut.

Kubernetes-Cluster (SKE)

Die STACKIT Kubernetes Engine übernimmt Control Plane und Node-Pools:

resource "stackit_ske_cluster" "platform" {
  project_id         = var.project_id
  name               = "platform-prod"
  kubernetes_version_min = "1.31"

  node_pools = [
    {
      name               = "workers"
      machine_type       = "c1a.4d"
      minimum            = 3
      maximum            = 6
      availability_zones = ["eu01-1", "eu01-2", "eu01-3"]
      os_version_min     = "4081.2"

      volume_size = 60
      volume_type = "storage_premium_perf1"
    }
  ]

  maintenance = {
    enable_kubernetes_version_updates    = true
    enable_machine_image_version_updates = true
    start                                = "02:00:00Z"
    end                                  = "04:00:00Z"
  }
}

Der Node-Pool skaliert zwischen minimum und maximum, verteilt über drei Availability Zones. Das Wartungsfenster nachts sorgt dafür, dass Patch-Updates automatisch laufen, ohne den Arbeitstag zu treffen.

Die Kubeconfig lässt sich als eigene Ressource ziehen und direkt an den Kubernetes-Provider weiterreichen:

resource "stackit_ske_kubeconfig" "platform" {
  project_id   = var.project_id
  cluster_name = stackit_ske_cluster.platform.name
  refresh      = true
}

Damit landet die Kubeconfig allerdings im State — behandeln Sie den State entsprechend als Secret.

PostgreSQL

PostgreSQL Flex liefert eine verwaltete Datenbank samt Backups:

resource "stackit_postgresflex_instance" "app_db" {
  project_id      = var.project_id
  name            = "app-prod"
  acl             = ["10.20.0.0/16"]
  backup_schedule = "0 2 * * *"
  flavor = {
    cpu = 4
    ram = 16
  }
  replicas = 3
  storage = {
    class = "premium-perf2-stackit"
    size  = 100
  }
  version = 16
}

resource "stackit_postgresflex_user" "app" {
  project_id  = var.project_id
  instance_id = stackit_postgresflex_instance.app_db.instance_id
  username    = "app"
  roles       = ["login"]
}

Die acl begrenzt den Zugriff auf das Netz des Clusters — nicht auf 0.0.0.0/0 setzen, auch nicht „nur kurz zum Testen“.

Object Storage und DNS

Für Artefakte, Backups oder statische Assets:

resource "stackit_objectstorage_bucket" "artifacts" {
  project_id = var.project_id
  name       = "acme-artifacts-prod"
}

resource "stackit_dns_zone" "main" {
  project_id    = var.project_id
  name          = "acme-prod"
  dns_name      = "acme.example"
  default_ttl   = 300
}

resource "stackit_dns_record_set" "app" {
  project_id = var.project_id
  zone_id    = stackit_dns_zone.main.zone_id
  name       = "app"
  type       = "A"
  records    = ["203.0.113.10"]
  ttl        = 300
}

Zwei Praxis-Hinweise

Terraform ist nicht der Ersatz für den State-Backend. Der STACKIT Object Storage ist S3-kompatibel und lässt sich als Remote Backend nutzen — die Zugangsdaten kommen dabei aus einer separaten Quelle, nicht aus demselben Terraform-Lauf, der den Bucket anlegt. Bucket und Backend gehören in getrennte Bootstrap-Schritte.

Trennen Sie Plattform und Anwendung. Cluster, Datenbank und Netzwerk gehören in einen Terraform-State, die Workloads darin nicht. Was im Cluster läuft, verwaltet besser Helm oder Argo CD — ein State, der Infrastruktur und Deployments mischt, blockiert bei jedem Rollout die Infrastrukturänderungen.

Fazit

Der STACKIT-Provider deckt die zentralen Bausteine ab: Kubernetes, Datenbanken, Storage, DNS und Netzwerk. Wer bereits Terraform-Erfahrung mit AWS oder Azure hat, findet sich schnell zurecht — die Muster sind dieselben, nur die Ressourcennamen ändern sich. Was hinzukommt, ist die Antwort auf eine Frage, die viele Kunden zunehmend stellen: Wo genau liegen unsere Daten?

Wir planen und betreiben STACKIT-Umgebungen — von der ersten Landing Zone bis zum laufenden Betrieb. Sprechen Sie uns an.

Timo Bergen

Timo Bergen

Gründer & Geschäftsführer