Veröffentlicht am

Terraform für Kubernetes: Infrastructure as Code

Teilen:
Authors

TL;DR

Terraform ermöglicht es, Kubernetes-Cluster und deren Workloads deklarativ als Code zu verwalten. Mit dem AWS-Provider erstellen Sie EKS-Cluster, mit dem Kubernetes- und Helm-Provider deployen Sie Ressourcen direkt. State-Management über Remote Backends wie S3 sichert die Zusammenarbeit im Team ab.

Warum Terraform für Kubernetes?

Kubernetes-Cluster manuell über die Cloud-Console zu erstellen funktioniert für ein einzelnes Projekt. Bei mehreren Umgebungen oder Teams wird das schnell unübersichtlich. Terraform löst dieses Problem: Infrastruktur wird als Code versioniert, reproduzierbar und automatisierbar.

# So sieht Kubernetes-Infrastruktur als Code aus
provider "aws" {
  region = "eu-central-1"
}

module "eks" {
  source          = "terraform-aws-modules/eks/aws"
  version         = "~> 20.0"
  cluster_name    = "production-cluster"
  cluster_version = "1.31"
  vpc_id          = module.vpc.vpc_id
  subnet_ids      = module.vpc.private_subnets

  eks_managed_node_groups = {
    default = {
      instance_types = ["m5.large"]
      min_size       = 2
      max_size       = 5
      desired_size   = 3
    }
  }
}

Drei Befehle genügen: terraform init, terraform plan, terraform apply. Der Cluster steht in etwa 15 Minuten.


Kubernetes-Provider vs. Helm-Provider

Terraform bietet zwei Wege, um Ressourcen in einen bestehenden Cluster zu deployen.

ProviderEinsatzzweckVorteil
kubernetesNative K8s-Ressourcen (Deployments, Services, ConfigMaps)Volle Kontrolle über jedes Feld
helmHelm Charts installierenWiederverwendbare Pakete, Community Charts

Kubernetes-Provider konfigurieren

provider "kubernetes" {
  host                   = module.eks.cluster_endpoint
  cluster_ca_certificate = base64decode(module.eks.cluster_certificate_authority_data)

  exec {
    api_version = "client.authentication.k8s.io/v1beta1"
    command     = "aws"
    args        = ["eks", "get-token", "--cluster-name", module.eks.cluster_name]
  }
}

Helm-Provider konfigurieren

provider "helm" {
  kubernetes {
    host                   = module.eks.cluster_endpoint
    cluster_ca_certificate = base64decode(module.eks.cluster_certificate_authority_data)

    exec {
      api_version = "client.authentication.k8s.io/v1beta1"
      command     = "aws"
      args        = ["eks", "get-token", "--cluster-name", module.eks.cluster_name]
    }
  }
}

In der Praxis nutzen die meisten Teams beide Provider: Helm für komplexe Anwendungen wie Ingress-Controller oder Monitoring-Stacks, den Kubernetes-Provider für eigene Deployments und Namespace-Konfigurationen.


Kubernetes-Ressourcen mit Terraform deployen

Ein vollständiges Deployment mit Service sieht in Terraform so aus:

resource "kubernetes_namespace" "app" {
  metadata {
    name = "webapp"
    labels = {
      environment = "production"
      managed-by  = "terraform"
    }
  }
}

resource "kubernetes_deployment" "webapp" {
  metadata {
    name      = "webapp"
    namespace = kubernetes_namespace.app.metadata[0].name
  }

  spec {
    replicas = 3

    selector {
      match_labels = { app = "webapp" }
    }

    template {
      metadata {
        labels = { app = "webapp" }
      }
      spec {
        container {
          name  = "webapp"
          image = "nginx:1.27"

          port {
            container_port = 80
          }

          resources {
            requests = {
              cpu    = "100m"
              memory = "128Mi"
            }
            limits = {
              cpu    = "250m"
              memory = "256Mi"
            }
          }
        }
      }
    }
  }
}

resource "kubernetes_service" "webapp" {
  metadata {
    name      = "webapp"
    namespace = kubernetes_namespace.app.metadata[0].name
  }

  spec {
    selector = { app = "webapp" }

    port {
      port        = 80
      target_port = 80
    }

    type = "ClusterIP"
  }
}

Der Vorteil gegenüber kubectl apply: Terraform kennt den Zielzustand und berechnet den Diff automatisch. Änderungen an Replicas oder Image-Versionen werden sauber geplant und angewendet.


State-Management richtig einrichten

Terraform speichert den aktuellen Zustand in einer State-Datei. Im Team darf diese nie lokal liegen. Nutzen Sie ein Remote Backend:

terraform {
  backend "s3" {
    bucket         = "mein-terraform-state"
    key            = "eks/production/terraform.tfstate"
    region         = "eu-central-1"
    dynamodb_table = "terraform-locks"
    encrypt        = true
  }
}

Die DynamoDB-Tabelle verhindert parallele Änderungen durch State Locking. Ohne dieses Locking riskieren Sie korrupte State-Dateien, wenn zwei Teammitglieder gleichzeitig terraform apply ausführen.

Modulstruktur für größere Projekte

Für produktive Setups hat sich diese Ordnerstruktur bewährt:

infrastructure/
├── modules/
│   ├── eks-cluster/
│   │   ├── main.tf
│   │   ├── variables.tf
│   │   └── outputs.tf
│   └── k8s-app/
│       ├── main.tf
│       └── variables.tf
├── environments/
│   ├── staging/
│   │   └── main.tf
│   └── production/
│       └── main.tf
└── backend.tf

Jede Umgebung referenziert dieselben Module mit unterschiedlichen Variablen. Staging bekommt kleinere Nodes und weniger Replicas, Production die volle Ausstattung.


Typische Fallstricke

Terraform vs. kubectl-Änderungen: Wenn jemand per kubectl edit eine Ressource ändert, erkennt Terraform beim nächsten plan den Drift und setzt die Änderung zurück. Einigen Sie sich im Team darauf, Änderungen ausschließlich über Terraform vorzunehmen.

Provider-Abhängigkeiten: Der Kubernetes-Provider braucht einen laufenden Cluster. Beim ersten apply eines neuen Clusters müssen Sie den Cluster zuerst separat erstellen oder -target nutzen.

Große State-Dateien: Bei hunderten Kubernetes-Ressourcen wird der State langsam. Teilen Sie den State auf: ein State für den Cluster, ein separater für die Workloads.


FAQ

Soll ich Kubernetes-Ressourcen mit Terraform oder mit Helm/kubectl verwalten?

Cluster-Infrastruktur (VPC, EKS, Node Groups) gehört in Terraform. Für Anwendungs-Deployments eignen sich GitOps-Tools wie ArgoCD oft besser, da sie schnellere Deployment-Zyklen ermöglichen.

Kann Terraform bestehende Kubernetes-Ressourcen importieren?

Ja, mit terraform import kubernetes_namespace.app webapp importieren Sie bestehende Ressourcen in den State. Ab Terraform 1.5 gibt es auch import-Blöcke direkt in HCL.

Wie gehe ich mit Secrets in Terraform um?

Secrets sollten nie im Terraform-Code stehen. Nutzen Sie den AWS Secrets Manager oder HashiCorp Vault und referenzieren Sie Secrets über Data Sources.

Ist Terraform oder Pulumi besser für Kubernetes?

Terraform hat das größere Ökosystem und mehr Community-Module. Pulumi bietet echte Programmiersprachen statt HCL. Für reine Infrastruktur-Provisionierung ist Terraform der etablierte Standard.

Kubernetes-Expertise gesucht?

Managed Services, Beratung, Training oder Security – wir unterstützen deutsche Unternehmen bei allen Kubernetes-Themen.

Kubernetes-Beratung gesucht?

Wir helfen deutschen Unternehmen bei der Kubernetes-Implementierung, Migration und Optimierung. DSGVO-konform und praxiserprobt.

📖 Verwandte Artikel

Weitere interessante Beiträge zu ähnlichen Themen