Files
2026-03-27 12:58:01 +01:00

531 lines
12 KiB
Markdown
Executable File
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#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.:
```hcl
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:
```hcl
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.
```hcl
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:
```hcl
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):
```hcl
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:
```hcl
module "network" {
source = "./modules/network"
vpc_cidr = "10.0.0.0/16"
}
```
Oder:
```hcl
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):
```hcl
terraform {
backend "s3" {
bucket = "my-terraform-state-bucket"
key = "prod/terraform.tfstate"
region = "eu-central-1"
}
}
```
---
## 3. Typischer Terraform-Workflow
### 3.1 Projektstruktur
Beispiel:
```text
.
├── 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:
```bash
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:
```hcl
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:
```hcl
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`
```hcl
terraform {
required_version = ">= 1.6.0"
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
}
provider "aws" {
region = var.region
}
```
### `variables.tf`
```hcl
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`
```hcl
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`
```hcl
output "web_instance_id" {
value = aws_instance.web.id
}
output "web_instance_ami" {
value = aws_instance.web.ami
}
```
Ablauf:
```bash
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`).
```bash
terraform workspace list
terraform workspace new dev
terraform workspace select dev
```
Dann z.B.:
```hcl
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:
```text
.
├── main.tf
├── modules
│ ├── network
│ │ ├── main.tf
│ │ ├── variables.tf
│ │ └── outputs.tf
│ └── compute
│ ├── main.tf
│ ├── variables.tf
│ └── outputs.tf
```
In `main.tf`:
```hcl
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.
---