Was ist Terraform?
Terraform von HashiCorp ist das meistgenutzte Infrastructure-as-Code (IaC) Tool. Statt Azure-Ressourcen manuell im Portal oder per Skript zu erstellen beschreiben Sie die gewünschte Infrastruktur in HCL (HashiCorp Configuration Language) – Terraform erstellt, aktualisiert und löscht Ressourcen automatisch.
Vorteile von IaC
| Aspekt | Manuell (Portal) | Terraform IaC |
|---|---|---|
| Reproduzierbarkeit | Nein | Ja (identische Umgebungen) |
| Versionierung | Keine | Git-Versionskontrolle |
| Dokumentation | Implizit | Code = Dokumentation |
| Rollback | Schwierig | terraform destroy + apply |
| Mehrere Umgebungen | Mühsam | Per Variable (dev/staging/prod) |
| Teamarbeit | Konflikte | Pull Requests, Code Reviews |
Terraform installieren
Linux
wget -O- https://apt.releases.hashicorp.com/gpg | gpg --dearmor | sudo tee /usr/share/keyrings/hashicorp-archive-keyring.gpg
echo "deb [signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] https://apt.releases.hashicorp.com $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/hashicorp.list
sudo apt update && sudo apt install -y terraform
terraform version
Windows
winget install HashiCorp.Terraform
Azure Provider konfigurieren
Service Principal erstellen
Terraform benötigt Berechtigungen um Azure-Ressourcen zu verwalten:
# Azure CLI installieren und einloggen
az login
# Service Principal erstellen
az ad sp create-for-rbac --name "terraform-sp" --role Contributor --scopes /subscriptions/<SUBSCRIPTION_ID>
# Ausgabe (notieren!):
# {
# "appId": "...", -> ARM_CLIENT_ID
# "password": "...", -> ARM_CLIENT_SECRET
# "tenant": "..." -> ARM_TENANT_ID
# }
Subscription ID ermitteln:
az account show --query id -o tsv
Umgebungsvariablen setzen
export ARM_SUBSCRIPTION_ID="<SUBSCRIPTION_ID>"
export ARM_TENANT_ID="<TENANT_ID>"
export ARM_CLIENT_ID="<APP_ID>"
export ARM_CLIENT_SECRET="<PASSWORD>"
Erstes Terraform-Projekt
Verzeichnisstruktur
mein-azure-projekt/
├── main.tf # Hauptkonfiguration
├── variables.tf # Variablen-Definitionen
├── outputs.tf # Ausgaben
├── terraform.tfvars # Variablenwerte (in .gitignore!)
└── providers.tf # Provider-Konfiguration
providers.tf
terraform {
required_version = ">= 1.5"
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = "~> 3.0"
}
}
}
provider "azurerm" {
features {}
}
main.tf – Resource Group und VNet
# Resource Group
resource "azurerm_resource_group" "main" {
name = var.resource_group_name
location = var.location
tags = {
Environment = var.environment
ManagedBy = "Terraform"
}
}
# Virtual Network
resource "azurerm_virtual_network" "main" {
name = "vnet-${var.environment}-${var.location}"
address_space = ["10.0.0.0/16"]
location = azurerm_resource_group.main.location
resource_group_name = azurerm_resource_group.main.name
}
# Subnetz
resource "azurerm_subnet" "internal" {
name = "subnet-internal"
resource_group_name = azurerm_resource_group.main.name
virtual_network_name = azurerm_virtual_network.main.name
address_prefixes = ["10.0.1.0/24"]
}
variables.tf
variable "resource_group_name" {
description = "Name der Resource Group"
type = string
}
variable "location" {
description = "Azure Region"
type = string
default = "germanywestcentral"
}
variable "environment" {
description = "Umgebung (dev, staging, prod)"
type = string
default = "dev"
}
terraform.tfvars
resource_group_name = "rg-meinefirma-dev"
location = "germanywestcentral"
environment = "dev"
outputs.tf
output "resource_group_id" {
value = azurerm_resource_group.main.id
}
output "vnet_id" {
value = azurerm_virtual_network.main.id
}
Terraform-Befehle
# Provider initialisieren (einmalig)
terraform init
# Plan – Was wird erstellt/geändert/gelöscht?
terraform plan
# Infrastruktur erstellen
terraform apply
# Bestätigung mit "yes" oder automatisch:
terraform apply -auto-approve
# Infrastruktur löschen
terraform destroy
# State anzeigen
terraform show
# Bestimmte Ressource neu erstellen
terraform taint azurerm_virtual_machine.main
terraform apply
Linux-VM erstellen
resource "azurerm_linux_virtual_machine" "server" {
name = "vm-server-01"
resource_group_name = azurerm_resource_group.main.name
location = azurerm_resource_group.main.location
size = "Standard_B2s"
admin_username = "azureuser"
network_interface_ids = [azurerm_network_interface.server.id]
admin_ssh_key {
username = "azureuser"
public_key = file("~/.ssh/id_ed25519.pub")
}
os_disk {
caching = "ReadWrite"
storage_account_type = "Standard_LRS"
disk_size_gb = 30
}
source_image_reference {
publisher = "Canonical"
offer = "0001-com-ubuntu-server-jammy"
sku = "22_04-lts-gen2"
version = "latest"
}
tags = {
Environment = var.environment
ManagedBy = "Terraform"
}
}
Remote State in Azure Storage
Für Teams sollte der Terraform-State nicht lokal liegen sondern in Azure Blob Storage:
terraform {
backend "azurerm" {
resource_group_name = "rg-terraform-state"
storage_account_name = "stterraformstate12345"
container_name = "tfstate"
key = "prod.terraform.tfstate"
}
}
# Storage Account einmalig erstellen
az group create -n rg-terraform-state -l germanywestcentral
az storage account create -n stterraformstate12345 -g rg-terraform-state -l germanywestcentral --sku Standard_LRS
az storage container create -n tfstate --account-name stterraformstate12345
FAQ
Terraform vs. Azure Bicep – was soll ich nutzen?
Terraform ist cloud-agnostisch (Azure, AWS, GCP mit demselben Tool). Bicep ist Azure-nativ, einfacher zu lernen und tiefer in Azure integriert. Für reine Azure-Shops: Bicep ist legitim. Für Multi-Cloud: Terraform.
Kann Terraform bestehende Azure-Ressourcen importieren?
Ja: terraform import azurerm_resource_group.main /subscriptions/.../resourceGroups/meine-rg
Wie verhindere ich versehentliches terraform destroy?
Lifecycle-Block: lifecycle { prevent_destroy = true } verhindert dass die Ressource per Terraform gelöscht werden kann.
Fazit
Terraform ist der Standard für Azure-IaC in professionellen Umgebungen. Wer einmal begonnen hat Infrastruktur als Code zu verwalten will nie zurück zum manuellen Portal-Klicken.
Wir implementieren Terraform-basierte Azure-Infrastrukturen für KMU in Heidelberg, Mannheim und der Rhein-Neckar-Region. Cloud-Beratung anfragen.