🏗️ Terraform Lektion 4/15 ~9 Min. Fortgeschritten

Provider und Multi-Cloud

AWS, Azure, GCP, Kubernetes Provider.

📝 Meine Notizen

Lernziele

Nach dieser Lektion kannst du erklären, was Terraform-Provider sind und wie sie Cloud-APIs anbinden. Du konfigurierst required_providers, Provider-Blöcke und Aliase für Multi-Region- oder Multi-Cluster-Setups. Du kennst den Unterschied zwischen Cloud-Providern und In-Cluster-Providern (Kubernetes, Helm) und weißt, wie du Provider-Versionen sicher pinnt.

Das Problem: eine Sprache, viele APIs

Terraform spricht HCL — AWS spricht EC2-API, Kubernetes spricht die kube-API, GitHub spricht REST. Ohne Adapter müsstest du für jede Plattform eigene Skripte schreiben. Provider sind genau diese Adapter: Go-Binäre, die Terraform herunterlädt und die eine einheitliche Resource/Data-Source-Syntax auf die jeweilige API mappen.

Das Problem in der Praxis ist nicht das Konzept, sondern die Konfiguration: falsche Region, abgelaufene Credentials, veraltete Provider-Version nach einem Breaking Change — und plötzlich scheitert plan mit kryptischen API-Fehlern, obwohl dein HCL syntaktisch korrekt ist.

Wie Provider eingebunden werden

Zwei Blöcke arbeiten zusammen:

terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 5.0"
    }
    kubernetes = {
      source  = "hashicorp/kubernetes"
      version = "~> 2.30"
    }
  }
}

provider "aws" {
  region = var.aws_region

  default_tags {
    tags = {
      ManagedBy   = "terraform"
      Environment = var.environment
    }
  }
}

provider "kubernetes" {
  host                   = var.kube_host
  cluster_ca_certificate = base64decode(var.kube_ca)
  token                  = var.kube_token
}

required_providers deklariert, welche Provider du brauchst, aus welcher Registry (hashicorp/aws auf registry.terraform.io) und mit welcher Versions-Constraint. provider-Blöcke konfigurieren die Verbindung — Region, Credentials, Endpoints.

Die Resource-Typen folgen dem Schema <provider>_<resource>: aws_s3_bucket, kubernetes_deployment, helm_release. Der Präfix verrät sofort, welcher Provider zuständig ist.

Credentials: nie in HCL, immer über die Umgebung

Provider authentifizieren sich über Mechanismen, die die jeweilige Plattform vorsieht:

  • AWS: Shared Credentials File, IAM-Rolle (in EC2/EKS/GitHub Actions), Umgebungsvariablen AWS_ACCESS_KEY_ID / AWS_SECRET_ACCESS_KEY, oder SSO
  • Azure: az login, Service Principal, Managed Identity
  • GCP: Application Default Credentials, Service Account JSON
  • Kubernetes: kubeconfig, In-Cluster-ServiceAccount-Token, exec-Plugin

Terraform hat keine eigene Credential-Verwaltung — es nutzt die Standard-Ketten der Plattform. In CI injizierst du Credentials als Secrets; lokal nutzt du Profile oder SSO. Hartcodierte Access Keys in .tf-Dateien gehören in kein Git-Repository.

Aliase: ein Provider, mehrere Kontexte

Wenn du Ressourcen in zwei AWS-Regionen oder zwei Kubernetes-Clustern verwaltest, brauchst du Provider-Aliase:

provider "aws" {
  alias  = "eu"
  region = "eu-central-1"
}

provider "aws" {
  alias  = "us"
  region = "us-east-1"
}

resource "aws_s3_bucket" "logs_eu" {
  provider = aws.eu
  bucket   = "logs-eu-${var.suffix}"
}

resource "aws_s3_bucket" "logs_us" {
  provider = aws.us
  bucket   = "logs-us-${var.suffix}"
}

Ohne provider = aws.eu im Resource-Block nutzt Terraform immer den default-Provider — den ohne Alias. Vergisst du das, legst du beide Buckets in derselben Region an.

Cloud-Provider vs. Kubernetes-Provider vs. Helm-Provider

Drei Ebenen, die Platform Engineers oft kombinieren:

EbeneProviderTypische Ressourcen
Cloudaws, azurerm, googleVPC, EKS/GKE/AKS, IAM, S3
ClusterkubernetesNamespace, Deployment, ConfigMap, RBAC
PaketehelmHelm Releases (Charts installieren)

Das übliche Muster: Cloud-Provider legt den Cluster an, Kubernetes-Provider konfiguriert Ressourcen darin, Helm-Provider installiert Charts. Die Reihenfolge im Abhängigkeitsgraphen ergibt sich aus Referenzen — der EKS-Cluster-Output liefert die kubeconfig für den Kubernetes-Provider (Lektion 9 geht tiefer).

Multi-Cloud bedeutet in Terraform: mehrere Cloud-Provider im selben Root-Modul oder — besser — getrennte Stacks pro Cloud mit terraform_remote_state als Schnittstelle (Lektion 6). Ein Monolith mit AWS und Azure und GCP in einer Konfiguration ist selten sinnvoll; getrennte State-Dateien und klare Ownership pro Cloud skaliert besser.

Provider-Versionen pinnen

Die Constraint ~> 5.0 erlaubt 5.x, aber kein 6.0 — ein sanftes Pinning. In .terraform.lock.hcl (generiert bei init) steht die exakte Version pro Plattform. Diese Lock-Datei committest du — sie garantiert, dass alle im Team und in CI dieselbe Provider-Version nutzen.

Breaking Changes kommen: Ein Major-Upgrade des AWS-Providers kann Attribute umbenennen oder Resources splitten. Vor dem Upgrade: Changelog lesen, terraform plan in Staging, ggf. moved-Blöcke nutzen (ab Terraform 1.1).

Praxis: zwei Provider in einem Projekt

mkdir providers-lab && cd providers-lab
cat > main.tf <<'EOF'
terraform {
  required_providers {
    random = {
      source  = "hashicorp/random"
      version = "~> 3.6"
    }
    local = {
      source  = "hashicorp/local"
      version = "~> 2.5"
    }
  }
}

resource "random_pet" "name" {
  length = 2
}

resource "local_file" "config" {
  filename = "${path.module}/output.txt"
  content  = "Hostname: ${random_pet.name.id}"
}
EOF

terraform init          # lädt beide Provider
terraform providers     # zeigt Provider-Abhängigkeiten
cat .terraform.lock.hcl # exakte Versionen
terraform apply
terraform destroy

terraform providers ist unterschätzt: Es zeigt, welche Module welche Provider brauchen — essenziell bei verschachtelten Modulen (Lektion 7).

Typische Stolperfallen

Provider-Version nicht gepinnt: Ohne required_providers-Block mit Version holt init die neueste Version — und ein Monat später bricht dein Plan wegen Breaking Changes. Pinne immer.

Default-Provider vs. Alias verwechseln: Ressourcen ohne provider-Attribut landen beim Default. Bei Multi-Region-Setups führt das zu Ressourcen in der falschen Region — oft erst beim Review oder der Rechnung auffällig.

Kubernetes-Provider ohne funktionierenden Cluster: plan scheitert, wenn die kube-API nicht erreichbar ist. Für reine Syntax-Checks reicht terraform validate; für plan brauchst du eine erreichbare API oder -refresh=false als Workaround (vorsichtig).

Community-Provider ohne Due Diligence: Nicht jeder Provider auf der Registry ist von HashiCorp gepflegt. Prüfe Maintainer, Issue-Aktivität und ob du den Source Code brauchst, bevor du ihn in Produktion einsetzt.

Interview-Vorbereitung

„Was ist ein Terraform-Provider?” — Ein Plugin, das Terraform mit einer API verbindet; Resources und Data Sources werden über <provider>_<type> adressiert. Konfiguration in provider-Blöcken, Deklaration in required_providers.

Follow-ups:

  • „Wie authentifiziert sich der AWS-Provider?” — Credential Chain: Env-Vars, Shared Config, IAM Role — kein Terraform-eigenes Secret-Management.
  • „Wofür Provider-Aliase?” — Mehrere Instanzen desselben Providers (Regionen, Cluster) in einem Modul.
  • „Unterschied kubernetes vs. helm Provider?” — kubernetes legt einzelne K8s-Ressourcen an; helm managed Releases (Templating + Revisionen).
  • „Wie sicherst du reproduzierbare Provider-Versionen?” — Version-Constraint + .terraform.lock.hcl committen.

Zusammenfassung

Provider sind die Brücke zwischen HCL und Cloud-APIs. Du deklarierst sie in required_providers, konfigurierst Verbindung und Credentials in provider-Blöcken und nutzt Aliase für Multi-Region- oder Multi-Cluster-Szenarien. Cloud-, Kubernetes- und Helm-Provider decken typischerweise die drei Ebenen einer Plattform ab. Versionen pinnt du mit Constraints und der Lock-Datei — das schützt vor überraschenden Breaking Changes.

In der nächsten Lektion widmen wir uns dem State — der Datei, ohne die Terraform keinen Diff berechnen kann.