Terraform - Infrastructure as Code in der Praxis. Ein vollstaendiger Leitfaden
Terraform Infrastructure as
devopsTerraform - Infrastructure as Code in der Praxis
Die Verwaltung von IT-Infrastruktur hat sich im Laufe der Jahre weiterentwickelt -- von manueller Serverkonfiguration ueber Automatisierungsskripte bis hin zum vollstaendigen Infrastructure-as-Code-Ansatz. Terraform, entwickelt von HashiCorp, ist eines der beliebtesten IaC-Tools, mit dem Sie Infrastruktur deklarativ definieren, versionieren und automatisch bereitstellen koennen. In diesem Leitfaden behandeln wir alle wesentlichen Aspekte der Arbeit mit Terraform -- von den Grundlagen der HCL-Syntax bis hin zu fortgeschrittenen Produktionsmustern.
Was ist Infrastructure as Code und warum brauchen Sie es?#
Infrastructure as Code (IaC) ist die Praxis der Verwaltung von IT-Infrastruktur durch Konfigurationsdateien anstelle manueller Prozesse. Anstatt sich in die AWS- oder Azure-Konsole einzuloggen und Buttons zu klicken, definieren Sie Ihre gesamte Infrastruktur in Textdateien, die in Git versioniert, in Pull Requests ueberprueft und automatisch ueber CI/CD-Pipelines bereitgestellt werden koennen.
Probleme ohne IaC#
Ohne einen IaC-Ansatz stossen Teams auf eine Reihe von Problemen:
- Snowflake-Server -- jeder manuell konfigurierte Server ist einzigartig, was die Reproduktion von Umgebungen erschwert
- Fehlende Wiederholbarkeit -- es gibt keine Garantie, dass Staging identisch mit der Produktion ist
- Konfigurationsdrift -- im Laufe der Zeit weichen Serverkonfigurationen vom beabsichtigten Zustand ab
- Kein Audit-Trail -- es ist schwer nachzuvollziehen, wer wann was und warum geaendert hat
- Langsame Bereitstellungen -- manuelle Konfiguration ist langsam und anfaellig fuer menschliche Fehler
Vorteile von IaC#
Die Einfuehrung eines IaC-Ansatzes loest diese Probleme:
- Versionskontrolle -- die gesamte Infrastruktur in Git mit vollstaendiger Aenderungshistorie
- Wiederholbarkeit -- identische Umgebungen mit einem einzigen Befehl erstellt
- Automatisierung -- Bereitstellungen ohne menschliches Eingreifen
- Dokumentation -- der Code selbst dient als Infrastrukturdokumentation
- Code Review -- Infrastruktuaenderungen werden wie Anwendungscode ueberprueft
- Schnelle Wiederherstellung -- Disaster Recovery reduziert sich auf das Ausfuehren eines Skripts
Terraform vs CloudFormation vs Pulumi#
Auf dem Markt gibt es mehrere IaC-Tools. Vergleichen wir die drei beliebtesten:
AWS CloudFormation#
CloudFormation ist das native IaC-Tool von AWS. Sein Hauptvorteil ist die tiefe Integration mit dem AWS-Oekosystem, aber es funktioniert ausschliesslich mit Amazon-Diensten. Konfigurationsdateien werden in JSON oder YAML geschrieben, was bei grossen Infrastrukturen unuebersichtlich wird.
Pulumi#
Pulumi ermoeglicht es, Infrastruktur mit gaengigen Programmiersprachen zu definieren -- TypeScript, Python, Go oder C#. Es ist eine grossartige Loesung fuer Teams, die Infrastruktur lieber in einer Sprache schreiben, die sie bereits kennen. Die Nachteile sind hoehere Komplexitaet und eine kleinere Community.
Terraform#
Terraform vereint die Vorteile beider Ansaetze. Es verwendet seine eigene Sprache HCL (HashiCorp Configuration Language), die deklarativ, lesbar und speziell fuer die Beschreibung von Infrastruktur konzipiert ist. Die wichtigsten Vorteile von Terraform sind:
- Multi-Cloud -- eine Sprache fuer AWS, Azure, GCP und Hunderte weiterer Provider
- Riesige Community -- Tausende von Modulen in der Terraform Registry
- Ausgereiftes Oekosystem -- ein stabiles Tool mit langjaehriger Geschichte
- Plan vor dem Deploy --
terraform planzeigt genau, was sich aendern wird - State Management -- Verfolgung des aktuellen Zustands der Infrastruktur
HCL-Syntax -- Die Grundlagen#
HashiCorp Configuration Language (HCL) ist eine deklarative Sprache, die speziell fuer HashiCorp-Tools entwickelt wurde. Ihre Syntax ist intuitiv und leicht zu erlernen.
Dateistruktur#
Ein typisches Terraform-Projekt besteht aus mehreren Dateien:
# main.tf - Hauptressourcenkonfiguration
# variables.tf - Variablendefinitionen
# outputs.tf - Ausgabewerte
# providers.tf - Provider-Konfiguration
# terraform.tf - Backend- und erforderliche Provider-Konfiguration
Konfigurationsbloecke#
HCL basiert auf Konfigurationsbloecken. Jeder Block hat einen Typ, optionale Labels und einen Body:
# Ressourcenblock
resource "aws_instance" "web_server" {
ami = "ami-0c55b159cbfafe1f0"
instance_type = "t3.micro"
tags = {
Name = "WebServer"
Environment = "production"
}
}
# Datenblock
data "aws_ami" "ubuntu" {
most_recent = true
filter {
name = "name"
values = ["ubuntu/images/hvm-ssd/ubuntu-jammy-22.04-amd64-server-*"]
}
owners = ["099720109477"] # Canonical
}
# Variablenblock
variable "instance_type" {
description = "EC2-Instanztyp"
type = string
default = "t3.micro"
validation {
condition = contains(["t3.micro", "t3.small", "t3.medium"], var.instance_type)
error_message = "Erlaubte Typen sind: t3.micro, t3.small, t3.medium."
}
}
Provider -- AWS, Azure, GCP#
Provider sind Plugins, die es Terraform ermoeglichen, mit Cloud-Plattformen und anderen Diensten zu kommunizieren. Jeder Provider stellt Ressourcen (Resources) und Datenquellen (Data Sources) bereit.
Provider-Konfiguration#
# providers.tf
terraform {
required_version = ">= 1.6.0"
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
azurerm = {
source = "hashicorp/azurerm"
version = "~> 3.0"
}
google = {
source = "hashicorp/google"
version = "~> 5.0"
}
}
}
# AWS-Provider
provider "aws" {
region = var.aws_region
default_tags {
tags = {
Project = var.project_name
Environment = var.environment
ManagedBy = "terraform"
}
}
}
# Azure-Provider
provider "azurerm" {
features {}
subscription_id = var.azure_subscription_id
}
# GCP-Provider
provider "google" {
project = var.gcp_project_id
region = var.gcp_region
}
Provider-Aliase#
Wenn Sie mehrere Instanzen desselben Providers benoetigen (z.B. verschiedene AWS-Regionen):
provider "aws" {
alias = "eu_west"
region = "eu-west-1"
}
provider "aws" {
alias = "us_east"
region = "us-east-1"
}
resource "aws_s3_bucket" "eu_bucket" {
provider = aws.eu_west
bucket = "my-eu-bucket"
}
resource "aws_s3_bucket" "us_bucket" {
provider = aws.us_east
bucket = "my-us-bucket"
}
Resources und Data Sources#
Resources#
Resources sind die wichtigsten Bausteine in Terraform. Jede Resource repraesentiert ein Infrastrukturelement, das Terraform erstellt und verwaltet:
# VPC erstellen
resource "aws_vpc" "main" {
cidr_block = "10.0.0.0/16"
enable_dns_hostnames = true
enable_dns_support = true
tags = {
Name = "${var.project_name}-vpc"
}
}
# Subnets erstellen
resource "aws_subnet" "public" {
count = length(var.availability_zones)
vpc_id = aws_vpc.main.id
cidr_block = cidrsubnet(var.vpc_cidr, 8, count.index)
availability_zone = var.availability_zones[count.index]
map_public_ip_on_launch = true
tags = {
Name = "${var.project_name}-public-${count.index + 1}"
Type = "public"
}
}
Data Sources#
Data Sources ermoeglichen es, Informationen ueber bestehende Ressourcen abzurufen, die nicht von Terraform verwaltet werden:
# Aktuelle AWS-Kontoinformationen abrufen
data "aws_caller_identity" "current" {}
# Verfuegbare Availability Zones abrufen
data "aws_availability_zones" "available" {
state = "available"
}
# Neuestes AMI abrufen
data "aws_ami" "amazon_linux" {
most_recent = true
owners = ["amazon"]
filter {
name = "name"
values = ["amzn2-ami-hvm-*-x86_64-gp2"]
}
}
# Data Source in einer Resource verwenden
resource "aws_instance" "app" {
ami = data.aws_ami.amazon_linux.id
instance_type = var.instance_type
availability_zone = data.aws_availability_zones.available.names[0]
}
Variablen und Outputs#
Eingabevariablen#
Variablen ermoeglichen die Parametrisierung Ihrer Terraform-Konfiguration:
# variables.tf
variable "environment" {
description = "Umgebungsname (dev, staging, prod)"
type = string
validation {
condition = contains(["dev", "staging", "prod"], var.environment)
error_message = "Umgebung muss sein: dev, staging oder prod."
}
}
variable "vpc_cidr" {
description = "CIDR-Block fuer die VPC"
type = string
default = "10.0.0.0/16"
}
variable "instance_count" {
description = "Anzahl der EC2-Instanzen"
type = number
default = 2
}
variable "allowed_cidrs" {
description = "Liste der erlaubten CIDRs in der Security Group"
type = list(string)
default = ["0.0.0.0/0"]
}
variable "tags" {
description = "Map von Tags zur Zuweisung an Ressourcen"
type = map(string)
default = {}
}
variable "db_config" {
description = "Datenbankkonfiguration"
type = object({
engine = string
engine_version = string
instance_class = string
allocated_storage = number
})
default = {
engine = "postgres"
engine_version = "15.4"
instance_class = "db.t3.micro"
allocated_storage = 20
}
}
Sensible Variablen#
Markieren Sie Variablen mit Geheimnissen als sensitive:
variable "db_password" {
description = "Datenbankpasswort"
type = string
sensitive = true
}
Outputs#
Outputs ermoeglichen den Export von Werten aus Ihrer Konfiguration:
# outputs.tf
output "vpc_id" {
description = "VPC-ID"
value = aws_vpc.main.id
}
output "public_subnet_ids" {
description = "Liste der oeffentlichen Subnet-IDs"
value = aws_subnet.public[*].id
}
output "instance_public_ips" {
description = "Oeffentliche IP-Adressen der Instanzen"
value = aws_instance.app[*].public_ip
}
output "rds_endpoint" {
description = "RDS-Datenbank-Endpunkt"
value = aws_db_instance.main.endpoint
sensitive = true
}
Terraform-Module#
Module ermoeglichen es, Terraform-Code zu organisieren und wiederzuverwenden. Ein Modul ist einfach ein Verzeichnis mit .tf-Dateien.
Modulstruktur#
modules/
├── vpc/
│ ├── main.tf
│ ├── variables.tf
│ ├── outputs.tf
│ └── README.md
├── ec2/
│ ├── main.tf
│ ├── variables.tf
│ └── outputs.tf
└── rds/
├── main.tf
├── variables.tf
└── outputs.tf
Ein Modul erstellen#
# modules/vpc/main.tf
resource "aws_vpc" "this" {
cidr_block = var.vpc_cidr
enable_dns_hostnames = true
enable_dns_support = true
tags = merge(var.tags, {
Name = "${var.name}-vpc"
})
}
resource "aws_internet_gateway" "this" {
vpc_id = aws_vpc.this.id
tags = merge(var.tags, {
Name = "${var.name}-igw"
})
}
resource "aws_subnet" "public" {
count = length(var.public_subnet_cidrs)
vpc_id = aws_vpc.this.id
cidr_block = var.public_subnet_cidrs[count.index]
availability_zone = var.availability_zones[count.index]
map_public_ip_on_launch = true
tags = merge(var.tags, {
Name = "${var.name}-public-${count.index + 1}"
})
}
resource "aws_subnet" "private" {
count = length(var.private_subnet_cidrs)
vpc_id = aws_vpc.this.id
cidr_block = var.private_subnet_cidrs[count.index]
availability_zone = var.availability_zones[count.index]
tags = merge(var.tags, {
Name = "${var.name}-private-${count.index + 1}"
})
}
Ein Modul verwenden#
# main.tf
module "vpc" {
source = "./modules/vpc"
name = var.project_name
vpc_cidr = "10.0.0.0/16"
public_subnet_cidrs = ["10.0.1.0/24", "10.0.2.0/24"]
private_subnet_cidrs = ["10.0.10.0/24", "10.0.11.0/24"]
availability_zones = ["eu-central-1a", "eu-central-1b"]
tags = local.common_tags
}
module "ec2" {
source = "./modules/ec2"
name = var.project_name
instance_type = var.instance_type
subnet_ids = module.vpc.public_subnet_ids
vpc_id = module.vpc.vpc_id
tags = local.common_tags
}
Module aus der Terraform Registry#
Sie koennen auch fertige Module aus der Registry verwenden:
module "vpc" {
source = "terraform-aws-modules/vpc/aws"
version = "5.4.0"
name = "my-vpc"
cidr = "10.0.0.0/16"
azs = ["eu-central-1a", "eu-central-1b", "eu-central-1c"]
private_subnets = ["10.0.1.0/24", "10.0.2.0/24", "10.0.3.0/24"]
public_subnets = ["10.0.101.0/24", "10.0.102.0/24", "10.0.103.0/24"]
enable_nat_gateway = true
single_nat_gateway = true
}
State Management#
Terraform speichert den Zustand Ihrer Infrastruktur in einer terraform.tfstate-Datei. Diese Datei ist kritisch -- sie bildet die im Code definierten Ressourcen auf die realen Ressourcen in der Cloud ab.
Remote State#
In einer Teamumgebung muss der State remote gespeichert werden:
# terraform.tf
terraform {
backend "s3" {
bucket = "my-terraform-state-bucket"
key = "prod/infrastructure/terraform.tfstate"
region = "eu-central-1"
encrypt = true
dynamodb_table = "terraform-state-lock"
}
}
State Locking#
DynamoDB bietet State Locking und verhindert gleichzeitige Aenderungen:
# DynamoDB-Tabelle fuer State Locking erstellen
resource "aws_dynamodb_table" "terraform_lock" {
name = "terraform-state-lock"
billing_mode = "PAY_PER_REQUEST"
hash_key = "LockID"
attribute {
name = "LockID"
type = "S"
}
tags = {
Name = "Terraform State Lock"
}
}
Azure-Backend#
Fuer Azure wird der State in Blob Storage gespeichert:
terraform {
backend "azurerm" {
resource_group_name = "tfstate-rg"
storage_account_name = "tfstateaccount"
container_name = "tfstate"
key = "prod.terraform.tfstate"
}
}
Workflow: plan, apply, destroy#
terraform init#
Initialisiert das Projekt -- laedt Provider und Module herunter:
terraform init
terraform plan#
Plan zeigt, welche Aenderungen vorgenommen werden, ohne sie auszufuehren:
terraform plan -out=tfplan
# Plan mit einer Variablendatei
terraform plan -var-file="prod.tfvars" -out=tfplan
terraform apply#
Wendet Aenderungen an:
# Gespeicherten Plan anwenden
terraform apply tfplan
# Direktes Apply mit Bestaetigung
terraform apply -var-file="prod.tfvars"
# Automatische Bestaetigung (CI/CD)
terraform apply -auto-approve -var-file="prod.tfvars"
terraform destroy#
Loescht alle Ressourcen:
# Mit Bestaetigung
terraform destroy -var-file="prod.tfvars"
# Bestimmte Ressource loeschen
terraform destroy -target=aws_instance.web_server
Beispiel: AWS-Infrastruktur bereitstellen#
Nachfolgend ein vollstaendiges Beispiel fuer die Erstellung einer AWS-Infrastruktur mit VPC, EC2, RDS und S3:
# main.tf - Vollstaendige AWS-Infrastruktur
locals {
common_tags = {
Project = var.project_name
Environment = var.environment
ManagedBy = "terraform"
}
}
# ==================== VPC ====================
resource "aws_vpc" "main" {
cidr_block = "10.0.0.0/16"
enable_dns_hostnames = true
enable_dns_support = true
tags = merge(local.common_tags, {
Name = "${var.project_name}-vpc"
})
}
resource "aws_internet_gateway" "main" {
vpc_id = aws_vpc.main.id
tags = merge(local.common_tags, {
Name = "${var.project_name}-igw"
})
}
resource "aws_subnet" "public" {
count = 2
vpc_id = aws_vpc.main.id
cidr_block = "10.0.${count.index + 1}.0/24"
availability_zone = data.aws_availability_zones.available.names[count.index]
map_public_ip_on_launch = true
tags = merge(local.common_tags, {
Name = "${var.project_name}-public-${count.index + 1}"
})
}
resource "aws_subnet" "private" {
count = 2
vpc_id = aws_vpc.main.id
cidr_block = "10.0.${count.index + 10}.0/24"
availability_zone = data.aws_availability_zones.available.names[count.index]
tags = merge(local.common_tags, {
Name = "${var.project_name}-private-${count.index + 1}"
})
}
resource "aws_route_table" "public" {
vpc_id = aws_vpc.main.id
route {
cidr_block = "0.0.0.0/0"
gateway_id = aws_internet_gateway.main.id
}
tags = merge(local.common_tags, {
Name = "${var.project_name}-public-rt"
})
}
resource "aws_route_table_association" "public" {
count = 2
subnet_id = aws_subnet.public[count.index].id
route_table_id = aws_route_table.public.id
}
# ==================== Security Groups ====================
resource "aws_security_group" "web" {
name_prefix = "${var.project_name}-web-"
vpc_id = aws_vpc.main.id
ingress {
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
ingress {
from_port = 443
to_port = 443
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
tags = merge(local.common_tags, {
Name = "${var.project_name}-web-sg"
})
lifecycle {
create_before_destroy = true
}
}
resource "aws_security_group" "rds" {
name_prefix = "${var.project_name}-rds-"
vpc_id = aws_vpc.main.id
ingress {
from_port = 5432
to_port = 5432
protocol = "tcp"
security_groups = [aws_security_group.web.id]
}
tags = merge(local.common_tags, {
Name = "${var.project_name}-rds-sg"
})
}
# ==================== EC2 ====================
resource "aws_instance" "web" {
count = var.instance_count
ami = data.aws_ami.amazon_linux.id
instance_type = var.instance_type
subnet_id = aws_subnet.public[count.index % 2].id
vpc_security_group_ids = [aws_security_group.web.id]
user_data = base64encode(templatefile("${path.module}/scripts/user_data.sh", {
environment = var.environment
db_endpoint = aws_db_instance.main.endpoint
}))
root_block_device {
volume_type = "gp3"
volume_size = 20
encrypted = true
}
tags = merge(local.common_tags, {
Name = "${var.project_name}-web-${count.index + 1}"
})
}
# ==================== RDS ====================
resource "aws_db_subnet_group" "main" {
name = "${var.project_name}-db-subnet"
subnet_ids = aws_subnet.private[*].id
tags = merge(local.common_tags, {
Name = "${var.project_name}-db-subnet-group"
})
}
resource "aws_db_instance" "main" {
identifier = "${var.project_name}-db"
engine = "postgres"
engine_version = "15.4"
instance_class = "db.t3.micro"
allocated_storage = 20
max_allocated_storage = 100
storage_encrypted = true
db_name = var.db_name
username = var.db_username
password = var.db_password
multi_az = var.environment == "prod" ? true : false
db_subnet_group_name = aws_db_subnet_group.main.name
vpc_security_group_ids = [aws_security_group.rds.id]
backup_retention_period = 7
skip_final_snapshot = var.environment != "prod"
tags = local.common_tags
}
# ==================== S3 ====================
resource "aws_s3_bucket" "assets" {
bucket = "${var.project_name}-assets-${var.environment}"
tags = merge(local.common_tags, {
Name = "${var.project_name}-assets"
})
}
resource "aws_s3_bucket_versioning" "assets" {
bucket = aws_s3_bucket.assets.id
versioning_configuration {
status = "Enabled"
}
}
resource "aws_s3_bucket_server_side_encryption_configuration" "assets" {
bucket = aws_s3_bucket.assets.id
rule {
apply_server_side_encryption_by_default {
sse_algorithm = "AES256"
}
}
}
resource "aws_s3_bucket_public_access_block" "assets" {
bucket = aws_s3_bucket.assets.id
block_public_acls = true
block_public_policy = true
ignore_public_acls = true
restrict_public_buckets = true
}
Workspaces#
Workspaces ermoeglichen die Verwaltung mehrerer Umgebungen aus einer einzigen Konfiguration:
# Workspaces erstellen
terraform workspace new dev
terraform workspace new staging
terraform workspace new prod
# Workspace wechseln
terraform workspace select prod
# Workspaces auflisten
terraform workspace list
Verwendung von Workspaces im Code:
locals {
environment = terraform.workspace
instance_type = {
dev = "t3.micro"
staging = "t3.small"
prod = "t3.medium"
}
}
resource "aws_instance" "app" {
instance_type = local.instance_type[local.environment]
# ...
}
CI/CD-Integration#
GitHub Actions#
# .github/workflows/terraform.yml
name: Terraform CI/CD
on:
push:
branches: [main]
pull_request:
branches: [main]
env:
TF_VERSION: "1.6.0"
AWS_REGION: "eu-central-1"
jobs:
terraform:
runs-on: ubuntu-latest
defaults:
run:
working-directory: ./infrastructure
steps:
- uses: actions/checkout@v4
- name: Setup Terraform
uses: hashicorp/setup-terraform@v3
with:
terraform_version: ${{ env.TF_VERSION }}
- name: Terraform Init
run: terraform init
- name: Terraform Format Check
run: terraform fmt -check -recursive
- name: Terraform Validate
run: terraform validate
- name: Terraform Plan
if: github.event_name == 'pull_request'
run: terraform plan -no-color -var-file="prod.tfvars"
- name: Terraform Apply
if: github.ref == 'refs/heads/main' && github.event_name == 'push'
run: terraform apply -auto-approve -var-file="prod.tfvars"
env:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
GitLab CI#
# .gitlab-ci.yml
stages:
- validate
- plan
- apply
variables:
TF_ROOT: "./infrastructure"
validate:
stage: validate
script:
- terraform init
- terraform fmt -check
- terraform validate
plan:
stage: plan
script:
- terraform init
- terraform plan -out=tfplan -var-file="prod.tfvars"
artifacts:
paths:
- ${TF_ROOT}/tfplan
apply:
stage: apply
script:
- terraform init
- terraform apply tfplan
when: manual
only:
- main
Best Practices#
1. Provider-Versionen festlegen#
Pinnen Sie immer Provider-Versionen, um unerwartete Aenderungen zu vermeiden:
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.31.0" # Erlaubt nur Patch-Updates
}
}
}
2. State Locking#
Verwenden Sie in Teamumgebungen immer State Locking. DynamoDB (AWS) oder Blob Lease (Azure) verhindert gleichzeitige State-Aenderungen.
3. Kleine, komponierbare Module#
Teilen Sie Ihre Infrastruktur in kleine, unabhaengige Module auf. Ein Modul pro logischer Komponente (VPC, Datenbank, Compute).
4. Variablen und Locals verwenden#
Hardcodieren Sie niemals Werte. Verwenden Sie Variablen fuer Eingabeparameter und locals fuer berechnete Werte:
locals {
name_prefix = "${var.project_name}-${var.environment}"
common_tags = {
Project = var.project_name
Environment = var.environment
ManagedBy = "terraform"
Team = var.team_name
}
}
5. Formatierung und Validierung#
Fuehren Sie vor dem Commit immer Formatierung und Validierung aus:
terraform fmt -recursive
terraform validate
6. .tfvars fuer Umgebungen verwenden#
# environments/prod.tfvars
environment = "prod"
instance_type = "t3.medium"
instance_count = 3
db_instance_class = "db.r6g.large"
# environments/dev.tfvars
environment = "dev"
instance_type = "t3.micro"
instance_count = 1
db_instance_class = "db.t3.micro"
7. Bestehende Ressourcen importieren#
Terraform 1.5+ unterstuetzt Import-Bloecke:
import {
to = aws_s3_bucket.existing
id = "my-existing-bucket"
}
resource "aws_s3_bucket" "existing" {
bucket = "my-existing-bucket"
}
Terraform Cloud#
Terraform Cloud ist die verwaltete Plattform von HashiCorp, die Folgendes bietet:
- Remote State Management -- sichere State-Speicherung mit Verschluesselung
- Remote Execution -- Plans und Applies werden auf HashiCorp-Servern ausgefuehrt
- Private Module Registry -- eine private Modul-Registry fuer Ihre Organisation
- Policy as Code -- Sentinel Policies zur Durchsetzung von Sicherheitsregeln
- Team Management -- Zugriffskontrolle und Berechtigungen
- Kostenschaetzung -- Kostenschaetzungen vor der Bereitstellung
- Drift Detection -- automatische Erkennung von Aenderungen ausserhalb von Terraform
terraform {
cloud {
organization = "my-organization"
workspaces {
name = "my-app-prod"
}
}
}
Zusammenfassung#
Terraform ist ein Tool, das die Verwaltung von IT-Infrastruktur grundlegend veraendert. Die wichtigsten Erkenntnisse sind:
- Infrastructure as Code -- die gesamte Infrastruktur als versionierter Code
- Multi-Cloud -- eine Sprache zur Verwaltung aller Plattformen
- Module -- Wiederverwendung und Standardisierung von Konfigurationen
- State Management -- praezise Verfolgung des Infrastrukturzustands
- CI/CD -- vollstaendige Automatisierung von Infrastrukturbereitstellungen
- Sicherheit -- State-Verschluesselung, State Locking, Policy as Code
Die Einfuehrung von Terraform in Ihrer Organisation ist eine Investition, die sich schnell durch erhoehte Wiederholbarkeit, schnellere Bereitstellungen und die Reduzierung menschlicher Fehler auszahlt.
Brauchen Sie Hilfe mit Terraform und Infrastruktur?#
Bei MDS Software Solutions Group sind wir auf das Design und die Bereitstellung von Cloud-Infrastruktur mit Terraform spezialisiert. Wir bieten:
- Cloud-Architekturdesign (AWS, Azure, GCP)
- Infrastructure-as-Code-Implementierung mit Terraform
- Migration bestehender Infrastruktur zum IaC-Ansatz
- CI/CD-Pipeline-Konfiguration fuer Infrastruktur
- Terraform- und DevOps-Schulungen
- Audit und Optimierung bestehender Terraform-Konfigurationen
Kontaktieren Sie uns, um Ihr Projekt zu besprechen!
Team von Programmierexperten, die sich auf moderne Webtechnologien spezialisiert haben.