Cloud-Kosten fest im Griff mit Infracost: Schätzen statt Staunen

Cloud-Services sind flexibel – aber oft teuer. Wenn Du Deine Infrastruktur planst, brauchst Du mehr als nur Bauchgefühl. Selbst gute Kostenschätzungen können ungenau sein, wenn wichtige Faktoren fehlen. Somit wird oft erst rückblickend klar, wie hoch die monatlichen Kosten tatsächlich sind.

Besonders in der Konzeptionsphase kann es schwerfallen, fundierte Aussagen über die zu erwartenden Betriebskosten zu treffen.

Das CLI Tool Infracost setzt genau hier an und ermöglicht die automatisierte Schätzung von Cloud-Infrastrukturkosten auf Grundlage bereits bestehender Terraform Ressourcen.

Da Cloud-Infrastruktur generell nicht manuell, sondern über Infrastructure as Code (IaC) Tools wie Terraform definiert, angelegt und verwaltet werden sollte, spiegeln die Terraform Ressourcen auch sehr gut die tatsächliche Cloud-Infrastruktur wider. Um die dafür anfallenden Kosten schätzen zu können, gleicht Infracost alle verwendeten Terraform Ressourcen mit der Infracost Cloud Pricing API ab, die einmal wöchentlich mit den offiziellen Preisen der Cloudanbieter AWS, Azure und Google aktualisiert wird.

Der Vorteil daran: Die Cloud-Infrastruktur muss noch gar nicht tatsächlich existieren. Alleine die Definition mittels Terraform reicht aus, um eine Kostenschätzung zu erhalten, also noch bevor die Cloud-Infrastruktur mittels „terraform apply“ ausgerollt wird. So lassen sich Kostenrisiken frühzeitig erkennen, Budgets realistisch planen und Entscheidungen datengestützt treffen. Infracost ist daher ideal für DevOps-Teams und Cloud-Architekt:innen, die Überraschungen vermeiden wollen.

So setzt du Infracost in der Praxis effektiv ein

Use Case 1 – Schon vor dem Rollout wissen, was deine Cloud kostet

Dieser Use Case skizziert den oben beschriebenen Fall, dass Terraform Ressourcen zwar definiert, jedoch noch nicht mittels „terraform apply“ angewandt wurden und die Cloud-Infrastruktur daher noch nicht beim geplanten Cloudanbieter existiert. Hierbei kommt der Befehl „infracost breakdown –path .“ zum Einsatz, der im Dateiverzeichnis der Terraform Ressourcen auszuführen ist. Dabei produziert Infracost beispielsweise eine folgende Ausgabe, die sich in diesem Beispiel auf Azure Ressourcen bezieht:

/

INFO Autodetected 1 Terraform project across 1 root module
INFO Found Terraform project main at directory . using Terraform var files terraform.tfvars

Project: main

Name Monthly Qty Unit Monthly Cost

module.azurerm_kubernetes.azurerm_kubernetes_cluster.kubernetes_cluster
└─ default_node_pool
├─ Instance usage (Linux, pay as you go, Standard_B2ms) 730 hours $70.08
└─ os_disk
└─ Storage (P10, LRS) 1 months $21.68

module.azurerm_container_registry.azurerm_container_registry.container_registry
├─ Registry usage (Standard) 30 days $20.00
├─ Storage (over 100GB) Monthly cost depends on usage: $0.10 per GB
└─ Build vCPU Monthly cost depends on usage: $0.0001 per seconds

module.azurerm_postgresql_database.azurerm_postgresql_flexible_server.database_server
├─ Compute (B_Standard_B1ms) 730 hours $14.53
├─ Storage 32 GB $4.38
└─ Additional backup storage Monthly cost depends on usage: $0.10 per GB

module.azurerm_kubernetes.azurerm_public_ip.public_ip
└─ IP address (static, regional) 730 hours $3.65

module.azurerm_postgresql_database.azurerm_private_dns_zone.dns_zone
└─ Hosted zone 1 months $0.50

module.azurerm_storage.azurerm_storage_account.storage_account
├─ Capacity Monthly cost depends on usage: $0.0196 per GB
├─ Write operations Monthly cost depends on usage: $0.054 per 10k operations
├─ List and create container operations Monthly cost depends on usage: $0.054 per 10k operations
├─ Read operations Monthly cost depends on usage: $0.0043 per 10k operations
├─ All other operations Monthly cost depends on usage: $0.0043 per 10k operations
└─ Blob index Monthly cost depends on usage: $0.039 per 10k tags

OVERALL TOTAL $134.82

*Usage costs can be estimated by updating Infracost Cloud settings, see docs for other options.

──────────────────────────────────
13 cloud resources were detected:
∙ 6 were estimated
∙ 7 were free

┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━┳━━━━━━━━━━━━┓
┃ Project ┃ Baseline cost ┃ Usage cost* ┃ Total cost ┃
┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╋━━━━━━━━━━━━━━━╋━━━━━━━━━━━━━╋━━━━━━━━━━━━┫
┃ main ┃ $135 ┃ – ┃ $135 ┃
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┻━━━━━━━━━━━━━━━┻━━━━━━━━━━━━━┻━━━━━━━━━━━━┛

Infracost schätzt in diesem Beispiel die initialen Gesamtkosten der geplanten Cloud-Infrastruktur pro Kalendermonat auf $135. Dabei werden standardmäßig jedoch nur die anfallenden Grundkosten (Baseline costs) berücksichtigt, also die fixen Kosten, die unabhängig der tatsächlichen Nutzungsdauer oder -häufigkeit der Cloud-Infrastruktur anfallen. Wenn du keine konkreten Mengen angibst, fehlen die Nutzungskosten (Usage costs) in der Schätzung. Das kann besonders bei Data-Driven Projekten zu sehr ungenauen Kostenschätzungen führen, da hier die Kosten stark mit der Datenmenge skaliert: Je mehr Daten über die Cloud-Infrastruktur zur Laufzeit empfangen, verarbeitet und gespeichert werden, desto höher sind deren Kosten. Ist also bereits ein möglichst konkretes Mengengerüst bekannt, sollte dieses über die Datei infracost-usage.yml angegeben werden (siehe Usage costs).

Möchte man jede Kostenschätzung in eine JSON-Datei umleiten und beispielsweise über Git versionieren, so kann der Befehl „infracost breakdown –path . –format json –out-file <costs-file>“ verwendet werden, der besonders in Use Case 3 interessant wird.

Use Case 2 – Wie teuer ist meine aktuelle Cloud-Infrastruktur

Dieser Use Case skizziert den Fall, dass Terraform Ressourcen bereits angewandt, jedoch keine Änderungen daran vorgenommen wurden. Auch hierbei kommt der Befehl „infracost breakdown –path .“ zum Einsatz, der zur selben Ausgabe wie in Use Case 1 führen sollte, sofern die Terraform Ressourcen zwischenzeitlich nicht verändert wurden.

Wichtig: Sobald tatsächliche Kosten beim Cloudanbieter entstehen, sollten diese Kosten regelmäßig mit den durch Infracost geschätzten Kosten abgeglichen werden, um diese zu validieren. Sind die tatsächlichen Kosten höher als die geschätzten Kosten, so werden entweder Cloud-Services in Anspruch genommen, die nicht mittels Terraform definiert wurden und daher für Infracost unbekannt sind oder die Nutzungskosten wurden gar nicht bzw. nur zu einem Teil berücksichtigt. Generell ist zu beachten, dass es sich in allen Fällen nur um eine Kostenschätzung handelt, die sich im besten Falle aber nur minimal von den tatsächlichen Kosten unterscheidet.

Use Case 3 – Kosten im Wandel: Wie wirken sich Änderungen auf meine Kosten aus?

Dieser Use Case skizziert den Fall, dass Änderungen an bereits angewandte Terraform Ressourcen vorgenommen werden, die sich auf die Kosten der Cloud-Infrastruktur auswirken. Im nachfolgenden Beispiel kam es exemplarisch zu einer Erhöhung einer Kubernetes Cluster Node Size von „Standard_B2ms“ auf „Standard_B4ms„. Hierbei kommt erneut der Befehl „infracost breakdown –path .“ zum Einsatz:

INFO Autodetected 1 Terraform project across 1 root module
INFO Found Terraform project main at directory . using Terraform var files terraform.tfvars

Project: main

Name Monthly Qty Unit Monthly Cost

module.azurerm_kubernetes.azurerm_kubernetes_cluster.kubernetes_cluster
└─ default_node_pool
├─ Instance usage (Linux, pay as you go, Standard_B4ms) 730 hours $140.16
└─ os_disk
└─ Storage (P10, LRS) 1 months $21.68

module.azurerm_container_registry.azurerm_container_registry.container_registry
├─ Registry usage (Standard) 30 days $20.00
├─ Storage (over 100GB) Monthly cost depends on usage: $0.10 per GB
└─ Build vCPU Monthly cost depends on usage: $0.0001 per seconds

module.azurerm_postgresql_database.azurerm_postgresql_flexible_server.database_server
├─ Compute (B_Standard_B1ms) 730 hours $14.53
├─ Storage 32 GB $4.38
└─ Additional backup storage Monthly cost depends on usage: $0.10 per GB

module.azurerm_kubernetes.azurerm_public_ip.public_ip
└─ IP address (static, regional) 730 hours $3.65

module.azurerm_postgresql_database.azurerm_private_dns_zone.dns_zone
└─ Hosted zone 1 months $0.50

module.azurerm_storage.azurerm_storage_account.storage_account
├─ Capacity Monthly cost depends on usage: $0.0196 per GB
├─ Write operations Monthly cost depends on usage: $0.054 per 10k operations
├─ List and create container operations Monthly cost depends on usage: $0.054 per 10k operations
├─ Read operations Monthly cost depends on usage: $0.0043 per 10k operations
├─ All other operations Monthly cost depends on usage: $0.0043 per 10k operations
└─ Blob index Monthly cost depends on usage: $0.039 per 10k tags

OVERALL TOTAL $204.90

*Usage costs can be estimated by updating Infracost Cloud settings, see docs for other options.

──────────────────────────────────
13 cloud resources were detected:
∙ 6 were estimated
∙ 7 were free

┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━┳━━━━━━━━━━━━┓
┃ Project ┃ Baseline cost ┃ Usage cost* ┃ Total cost ┃
┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╋━━━━━━━━━━━━━━━╋━━━━━━━━━━━━━╋━━━━━━━━━━━━┫
┃ main ┃ $205 ┃ – ┃ $205 ┃
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┻━━━━━━━━━━━━━━━┻━━━━━━━━━━━━━┻━━━━━━━━━━━━┛

Infracost schätzt die Kosten der geänderten Cloud-Infrastruktur pro Kalendermonat nun auf $205 was eine Erhöhung im Vergleich zu Use Case 2 in Höhe von $70 darstellt.

Um die Kostendifferenz nicht selbst berechnen zu müssen, kann alternativ „infracost diff –path <new-costs-file> –compare-to <old-costs-file>“ verwendet werden, der zu folgender Ausgabe führt:

Key: * usage cost, ~ changed, + added, – removed

──────────────────────────────────
Project: main

~ module.azurerm_kubernetes.azurerm_kubernetes_cluster.kubernetes_cluster
+$70 ($92 → $162)

~ default_node_pool

~ Instance usage (Linux, pay as you go, Standard_B2ms → Standard_B4ms)
+$70 ($70 → $140)

Monthly cost change for Kunde_doubleSlash/update-manager/additional/dsum-infrastructure/terraform/environments/dev
Amount: +$70 ($135 → $205)
Percent: +52%

──────────────────────────────────
Key: * usage cost, ~ changed, + added, – removed

*Usage costs can be estimated by updating Infracost Cloud settings, see docs for other options.

13 cloud resources were detected:
∙ 6 were estimated
∙ 7 were free

Infracost estimate: Monthly estimate increased by $70 ↑
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━┳━━━━━━━━━━━━━━┓
┃ Changed project ┃ Baseline cost ┃ Usage cost* ┃ Total change ┃
┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╋━━━━━━━━━━━━━━━╋━━━━━━━━━━━━━╋━━━━━━━━━━━━━━┫
┃ Kunde_doubleSlash/update-manage…ure/terraform/environments/dev ┃ +$70 ┃ – ┃ +$70 (+52%) ┃
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┻━━━━━━━━━━━━━━━┻━━━━━━━━━━━━━┻━━━━━━━━━━━━━━┛

Dieser Ansatz ist besonders für die Verwendung von Infracost in einer automatisierten CI/CD Pipeline sinnvoll, wobei die ältere der beiden JSON-Dateien z. B. mittels Git versioniert und mit einer neu angelegten JSON-Datei verglichen werden kann. Für die nächste Ausführung der Pipeline muss die versionierte JSON-Datei dann mit der neu angelegte JSON-Datei überschrieben werden, damit sie die Kostenschätzung der tatsächlich angewandten Terraform Ressourcen enthält.

Nicht jeder kann alles wissen

Infracost unterstützt aktuell rund 1.100 Terraform-Ressourcen. Nutzt Du Services, die (noch) nicht unterstützt werden, kann die Schätzung unvollständig sein.

Mit Infracost unangenehme Überraschungen vermeiden

Infracost bietet einen enormen Mehrwert, wenn es darum geht, Cloud-Infrastrukturkosten im Zusammenspiel mit Terraform vorausschauend zu planen. Wer Infrastructure as Code (IaC) lebt, sollte auch „Costs as Code“ denken. Mit Infracost wird genau das möglich.

Aus zwei Gründen sollte dennoch stets gelten: Vertrauen ist gut, Kontrolle ist besser!

Grund 1: Eine Kostenschätzung ist nunmal eine Kostenschätzung und muss nicht zwangsläufig den tatsächlichen Kosten entsprechen.

Grund 2: Eine Kostenschätzung ist nur so gut wie die Informationen, die dabei berücksichtigt wurden. Ein fehlendes oder unzureichendes Mengengerüst kann die Kostenschätzung aufgrund falscher Nutzungskosten stark verfälschen.

Der Beitrag Cloud-Kosten fest im Griff mit Infracost: Schätzen statt Staunen erschien zuerst auf Business -Software- und IT-Blog – Wir gestalten digitale Wertschöpfung.