Files
work/notes/nextcloud/Notes/IT-Know-How/web und cloud gedoens/Terraform.md
T
2026-03-17 19:04:55 +01:00

12 KiB
Executable File
Raw Blame History

#infrastructure #Cloud

1. Was ist Terraform?

Terraform ist ein Open-Source-Tool (ursprünglich MIT, seit 2023 Business Source License, BSL) von HashiCorp zur deklarativen Beschreibung und Verwaltung von Infrastruktur als Code (Infrastructure as Code, IaC).

Mit Terraform kannst du:

  • Infrastruktur in Cloud-Providern (AWS, Azure, GCP, …), On-Premise und weiteren Systemen beschreiben (als Code).
  • Aus dieser Beschreibung eine gewünschte Zielkonfiguration (Desired State) definieren.
  • Terraform berechnet dann, welche Änderungen nötig sind, um vom Ist-Zustand zum Soll-Zustand zu gelangen.
  • Diese Änderungen werden mit terraform apply automatisch ausgeführt.

Terraform ist besonders stark in:

  • Multi-Cloud- und Hybrid-Szenarien
  • Reproduzierbaren Umgebungen (z.B. Dev, Test, Prod)
  • Versionierbarer Infrastruktur (Git)
  • Team-Kollaboration an Infrastruktur

2. Grundkonzepte von Terraform

Die wichtigsten Bausteine:

2.1 Provider

Provider sind die „Treiber“, mit denen Terraform mit einem externen System spricht, z.B.:

  • aws Amazon Web Services
  • azurerm Microsoft Azure
  • google Google Cloud
  • kubernetes Kubernetes-Cluster
  • helm, docker, vault, github, viele weitere

In Terraform-Code bindet man einen Provider ein, z.B.:

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

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

2.2 Ressourcen

Ressourcen (resource) sind die eigentlichen Infrastruktur-Objekte, z.B.:

  • aws_instance (EC2-VM)
  • aws_s3_bucket
  • azurerm_resource_group
  • google_compute_instance

Beispiel:

resource "aws_s3_bucket" "example" {
  bucket = "mein-terraform-bucket-12345"
  acl    = "private"
}

aws_s3_bucket ist der Ressourcentyp, "example" der Name innerhalb der Terraform-Konfiguration.

2.3 Datenquellen (Data Sources)

data-Blöcke lesen Informationen aus einer bestehenden Umgebung, ohne etwas zu verändern.

data "aws_ami" "ubuntu" {
  most_recent = true

  filter {
    name   = "name"
    values = ["ubuntu/images/hvm-ssd/ubuntu-focal-20.04-amd64-server-*"]
  }

  owners = ["099720109477"] # Canonical
}

Die Daten können dann in Ressourcen verwendet werden.

2.4 Variablen und Outputs

Variablen (variable) erlauben Parametrisierung:

variable "region" {
  type        = string
  default     = "eu-central-1"
  description = "AWS Region"
}

Aufgerufen z.B.: var.region.

Outputs (output) geben wichtige Informationen aus (z.B. IP-Adressen):

output "instance_ip" {
  value = aws_instance.web.public_ip
}

2.5 Module

Module sind wiederverwendbare Bausteine von Terraform-Konfigurationen (eine Art „Bibliothek“ von Infrastruktur).

  • Ein Modul ist einfach ein Ordner mit .tf-Dateien.
  • Man kann eigene Module oder Community-Module nutzen (z.B. aus dem Terraform Registry).

Beispiel Nutzung eines Moduls:

module "network" {
  source = "./modules/network"

  vpc_cidr = "10.0.0.0/16"
}

Oder:

module "vpc" {
  source  = "terraform-aws-modules/vpc/aws"
  version = "5.0.0"

  name = "main-vpc"
  cidr = "10.0.0.0/16"
  azs  = ["eu-central-1a", "eu-central-1b"]
}

2.6 Terraform State

Terraform hält den Zustand der verwalteten Ressourcen in einer State-Datei (terraform.tfstate) fest.

  • Der State ist die „Wahrheit“, mit der Terraform den Ist-Zustand kennt.
  • Daran erkennt Terraform, welche Ressource es schon erstellt hat und wie deren IDs, Attribute usw. sind.
  • Änderungen am Code werden mit dem State abgeglichen → Terraform generiert einen Plan.

State kann liegen:

  • lokal: terraform.tfstate im Projektordner
  • remote (empfohlen für Teams): z.B. in S3, Azure Storage, GCS, Terraform Cloud, etc.

Beispiel Backend-Konfiguration (Remote State mit S3):

terraform {
  backend "s3" {
    bucket = "my-terraform-state-bucket"
    key    = "prod/terraform.tfstate"
    region = "eu-central-1"
  }
}

3. Typischer Terraform-Workflow

3.1 Projektstruktur

Beispiel:

.
├── main.tf       # Ressourcen, Module
├── variables.tf  # Variablen
├── outputs.tf    # Outputs
└── providers.tf  # Provider / Backend

3.2 Wichtige Terraform-Kommandos

  1. terraform init

    • Initialisiert das Projekt
    • Lädt Provider-Plugins
    • Konfiguriert Backend (State)
  2. terraform plan

    • Zeigt, was Terraform ändern würde (Create/Update/Delete)
    • Verändert noch nichts
    • Wichtig für Review (z.B. im CI)
  3. terraform apply

    • Führt den Plan aus (Standard: vorher Anzeige + Bestätigung)
    • Erzeugt/aktualisiert/löscht Ressourcen
  4. terraform destroy

    • Löscht alle Ressourcen, die Terraform verwaltet
    • Vorsicht: de facto „Infrastruktur-Abbau“

Typischer Ablauf:

terraform init
terraform plan
terraform apply

4. Terraform-Sprache: HCL (HashiCorp Configuration Language)

Terraform benutzt HCL, eine deklarative, blockbasierte Sprache.

4.1 Syntax-Grundlagen

Blöcke haben Form:

resource "TYP" "NAME" {
  argument = "value"

  block {
    nested_arg = 123
  }
}

Datentypen:

  • string "Text"
  • number 42
  • bool true / false
  • Listen ["a", "b"]
  • Maps { key = "value" }
  • Objekte/Tuples komplexere Typen

4.2 Expressions & Referenzen

Referenzen auf andere Ressourcen:

resource "aws_instance" "web" {
  ami           = data.aws_ami.ubuntu.id
  instance_type = var.instance_type

  tags = {
    Name = "web-${var.environment}"
  }
}

Referenz-Regel:

  • ressourcentyp.name.attribut
  • z.B. aws_instance.web.public_ip

5. Praktisches Beispiel

Ein minimaler Stack in AWS:

providers.tf

terraform {
  required_version = ">= 1.6.0"

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

provider "aws" {
  region = var.region
}

variables.tf

variable "region" {
  type        = string
  default     = "eu-central-1"
  description = "AWS Region"
}

variable "instance_type" {
  type        = string
  default     = "t3.micro"
}

variable "environment" {
  type        = string
  default     = "dev"
}

main.tf

data "aws_ami" "ubuntu" {
  most_recent = true

  filter {
    name   = "name"
    values = ["ubuntu/images/hvm-ssd/ubuntu-focal-20.04-amd64-server-*"]
  }

  owners = ["099720109477"]
}

resource "aws_instance" "web" {
  ami           = data.aws_ami.ubuntu.id
  instance_type = var.instance_type

  tags = {
    Name        = "web-${var.environment}"
    Environment = var.environment
  }
}

outputs.tf

output "web_instance_id" {
  value = aws_instance.web.id
}

output "web_instance_ami" {
  value = aws_instance.web.ami
}

Ablauf:

terraform init
terraform plan
terraform apply

6. Workspaces, Environments und Modularisierung

6.1 Workspaces

Terraform Workspaces ermöglichen getrennte States innerhalb desselben Codes (z.B. default, dev, prod).

terraform workspace list
terraform workspace new dev
terraform workspace select dev

Dann z.B.:

variable "environment" {
  default = terraform.workspace
}

Viele Teams gehen aber eher über separate State-Dateien / Ordner / Repos (z.B. envs/dev, envs/prod), statt Workspaces intensiv zu nutzen.

6.2 Module für Wiederverwendung

Struktur-Beispiel:

.
├── main.tf
├── modules
│   ├── network
│   │   ├── main.tf
│   │   ├── variables.tf
│   │   └── outputs.tf
│   └── compute
│       ├── main.tf
│       ├── variables.tf
│       └── outputs.tf

In main.tf:

module "network" {
  source   = "./modules/network"
  vpc_cidr = "10.0.0.0/16"
}

module "compute" {
  source   = "./modules/compute"
  vpc_id   = module.network.vpc_id
  subnets  = module.network.subnet_ids
}

7. Terraform Cloud / Terraform Enterprise

Neben der CLI gibt es:

  • Terraform Cloud (SaaS von HashiCorp)
  • Terraform Enterprise (Self-hosted)

Features:

  • Remote-State-Storage
  • Remote-Execution (Plans/Applies)
  • Policies (Sentinel)
  • Team & Governance (RBAC)
  • UI für Runs, Logs, States, Variablen

Für kleine Teams reicht oft: Git + Remote State (S3/Azure/GCS) + CI/CD Pipeline.


8. Typische Anwendungsfälle

  • Cloud-Infrastruktur:
    • VPCs/Netzwerke, Subnets, Security Groups
    • Compute (VMs, Managed Kubernetes, Serverless)
    • Datenbanken, Caches, Messaging
  • Kubernetes-Infrastruktur:
    • Cluster (EKS/AKS/GKE)
    • Add-ons via kubernetes-Provider, helm-Provider
  • Multi-Cloud-Szenarien:
    • Einheitliches Tool für AWS + Azure + GCP
  • On-Prem / Sonstiges:
    • VMware, OpenStack, F5, GitHub-Repos, DNS (Cloudflare/Route53), Monitoring (Datadog, New Relic), etc.

9. Vergleich zu anderen Tools

Terraform vs. CloudFormation / ARM / Bicep

  • Terraform:
    • Provider-übergreifend (nicht auf eine Cloud beschränkt)
    • HCL, verständliche Syntax
  • CloudFormation (AWS) / ARM/Bicep (Azure) / Deployment Manager (GCP):
    • Cloud-spezifisch, tief integriert
    • Gut für reines Single-Cloud-Setup
    • Multi-Cloud wird komplex

Terraform vs. Ansible / Chef / Puppet

  • Terraform:
    • Fokus: Provisioning + Lebenszyklus von Ressourcen
    • Deklarativ, fokus auf Infrastruktur
  • Ansible/Chef/Puppet:
    • Fokus: Konfiguration von Servern / Software
    • IdR. auf bereits existierende Maschinen

Häufig werden Terraform + Ansible kombiniert:
Terraform baut VMs / Netzwerke, Ansible konfiguriert Software im OS.

Terraform vs. Pulumi

  • Pulumi: IaC mit allgemeinen Programmiersprachen (TypeScript, Python, Go, C#)
  • Terraform: HCL, deklarativ, stark verbreitete Community
  • Pulumi bietet mehr „Programmier-Features“ (Loops, Ifs) direkt in Sprache; Terraform hat ähnliche Mechanismen, aber bewusst begrenzt, um die Konfiguration simpel zu halten.

10. Best Practices & Stolperfallen

10.1 Best Practices

  • State nicht lokal speichern, sondern Remote (z.B. S3 + DynamoDB Locking, Azure Storage + Locks).
  • State schützen:
    • Zugriff beschränken (IAM/RBAC)
    • Backups
  • Struktur / Modularisierung:
    • Wiederverwendbare Module
    • Trennung von Environments (dev/stage/prod)
  • Git-Workflow:
    • Terraform-Code in Repos
    • PRs/Merge-Requests
    • terraform plan via CI im PR anzeigen
  • Versionen pinnen:
    • Terraform-Version required_version
    • Provider-Versionen fixieren (z.B. ~> 5.0)
  • Kleine, inkrementelle Änderungen:
    • Große Umbauten in mehreren Schritten
    • Plan gut reviewen

10.2 Typische Probleme

  • State-Drift:
    • Ressourcen werden außerhalb von Terraform geändert (z.B. in der Cloud-Konsole)
    • Plan zeigt unerwartete Änderungen
    • Lösung: soweit möglich alle Änderungen via Terraform; bei Drift bewusst entscheiden (import, adopt, ignore)
  • Manuelles Löschen von Ressourcen:
    • Terraform „denkt“, Ressource existiert noch
    • Beim nächsten Apply werden sie ggf. neu erstellt
  • Zyklen in Abhängigkeiten:
    • Falsche Referenzen können zyklische Abhängigkeiten erzeugen
  • Große States:
    • Sehr viele Ressourcen in einem State → langsamere Plans, unübersichtliche Fehler
    • Lösung: Aufteilen in mehrere Terraform-Projekte / States (z.B. pro Domäne/Layer)

11. Aktuelle Entwicklungen: Lizenz & OpenTofu

HashiCorp hat 2023 die Lizenz von Terraform auf die Business Source License (BSL) geändert.
Daraufhin entstand ein Community-Fork:

  • OpenTofu (ehemals OpenTF):
    • Komplett Open Source (MPL 2.0)
    • CLI & HCL weitgehend kompatibel zu Terraform (Stand heute)
    • Ziel: drop-in Replacement für viele Terraform-Usecases

Für einen Einstieg in IaC ist es aber sinnvoll, zuerst die Konzepte anhand von Terraform zu verstehen die meisten davon sind für OpenTofu nahezu identisch.