Infrastructure-as-Code (IaC): Bicep und Terraform im Vergleich

Infrastructure as Code (IaC) ist eine wichtige Technik in der Automatisierung. Teams beginnen ihren Weg zu Cloud-Native oft so, dass sie alles automatisieren und die Infrastruktur ist hier keine Ausnahme. Die stetig wachsende Akzeptanz von Cloud-Diensten und die Digitalisierung sind nur einige Gründe, warum IaC-Tools wie Terraform so beliebt sind. Project Bicep ist hier ganz neu - eine neue Sprache, die erstellt wurde, um Azure Infrastruktur-Deployments als Code auszudrücken

In diesem Artikel:

Dieser Artikel ist eine deutsche Übersetzung. Den Originalartikel in englischer Sprache finden Sie in Thorsten Hans‘ Blog.

Umfang des Vergleichs

Dieser Artikel vergleicht Projekt Bicep und HashiCorp Terraform. Er beinhaltet

  • eine Bewertung der Unterschiede zwischen Bicep und Terraform
  • Vergleich von

    • Bereitstellungsmethoden
    • Sprachsyntax
    • Tooling

Dieser Artikel enthält keine Einführung in die Bicep-Syntax. Das Produktteam und die lebhafte Open-Source-Community bieten ein gutes Tutorial und eine beeindruckende Menge an Beispielen an. Sie sollten etwas Zeit investieren, um das Tutorial durchzuarbeiten und einige Beispiele durchsehen, um ein grundlegendes Verständnis für die Sprache selbst zu erlangen. Mein Freund Tobias Zimmergren hat auch einen tollen Artikel über Bicep veröffentlicht. Es lohnt sich, diesen zu lesen.

Was ist Bicep?

Bicep ist eine relativ neue, deklarative domänenspezifische Sprache (DSL), die von Microsoft entwickelt wurde. Sie transpiliert zu Azure ARM-Templates. Deshalb haben Sie Zugriff auf alle Ressourcen und deren Eigenschaften in allen verfügbaren Versionen. Im Vergleich zu den zugrunde liegenden ARM-Templates können Entwickler Azure-Infrastrukturen mit deutlich weniger Code ausdrücken.

Das Team verfolgt die folgenden hochrangigen Ziele:

  1. Bicep bietet die beste User-Experience (UX), wenn es um die Bereitstellung, Beschreibung und Validierung von Azure-Infrastrukturen geht.
  2. Bicep soll eine transparente Abstraktion der zugrundeliegenden Cloud-Plattform sein. Es sollte keinerlei „Opt-Ins“ für neue Azure-Dienste oder neue Dienstversionen erfordern.
  3. Die Bicep-Sprache soll für jeden Entwickler leicht zu lesen, zu lernen und zu verstehen sein.
  4. Refactorings, Strukturierung und Modularisierung sollten unkompliziert und flexibel sein.
  5. Produktivität und umfangreiches Tooling werden parallel zum Bicep Compiler entwickelt, um ein außerordentliches Entwicklererlebnis zu gewährleisten.
  6. Das Tooling sollte das Vertrauen der Benutzer stärken. Entwickler sollten wissen, ob ihr Code valide ist, bevor sie Diesen bereitstellen.

Was bietet Bicep nicht?

Das Bicep-Team weist darauf hin, was nicht im Scope ist:

  • Bicep wird nicht zu einer Allzwecksprache entwickelt. Das heißt, Sie brauchen oft ein bisschen Framing. Denken Sie an Skripte, die vor oder nach einer Bicep-basierten Bereitstellung ausgeführt werden.
  • Bicep wird kein Modell für nicht-Azure-bezogene Tasks bereitstellen. Obwohl dies technisch möglich wäre. Das Team konzentriert sich auf Azure.

Bicep im Vergleich zu Terraform

In den folgenden Abschnitten werden Bicep und Terraform anhand von drei wesentlichen Kriterien verglichen:

  • Bereitstellungsmethoden
  • Sprachsyntax
  • Tooling

Bereitstellungsmethoden

Terraform verwendet Desired State Configuration (DSC) als Grundkonzept. Terraform ruft hierzu die zugrundeliegenden Cloud-Infrastruktur-APIs auf und ändert die Zielumgebung (z. B. Azure) so, dass sie dem vom Benutzer definierten gewünschten Zustand entspricht. Jedes Terraform-Projekt hat einen Lebenszyklus, und die Terraform CLI unterstützt Benutzer beim Erstellen, Mutieren und Löschen von Infrastrukturen.

Im Gegensatz dazu verwendet Bicep standardmäßig inkrementelle Bereitstellungen, wie die zugrundeliegenden ARM-Templates. Inkrementelle Bereitstellungen können Azure-Dienste in einem konfigurierbaren Bereich (Resource GroupSubscriptionManagement Group oder Tenant) hinzufügen oder ändern. Aufgrund inkrementeller Bereitstellungen löscht Bicep niemals eine Service-Instanz aus Azure, wenn Sie diese aus Ihrem Quellcode entfernen.

Darüber hinaus können Sie Bicep-Projekte im vollständigen Bereitstellungsmodus bereitstellen. Bereitstellungen, die im Modus complete erstellt wurden, führen dazu, dass alle Ressourcen aus dem Zielbereich entfernt werden, die nicht Teil der angewendeten Vorlage sind. Dies kann sich auch auf Ressourcen auswirken, die nicht zum Umfang des Bicep-Projekts gehören, aber derselben Azure-Ressourcengruppe angehören.

Vergleicht man beide, ist Bicep (mit dem inkrementellen Bereitstellungsmodus) in erster Linie robuster. Man kann einen Produktionsdienst nicht versehentlich löschen, indem man einige Codezeilen aus dem Quellcode entfernt. Dies führt jedoch dazu, dass Bicep zu einem möglichen Konfigurationsdrift führt. Konfigurationsdrift ist der Unterschied zwischen dem in der Codebasis beschriebenen Zustand und der tatsächlichen Infrastruktur.

Auf der anderen Seite hängt jedes Terraform-Projekt stark von der State-Datei ab. Die Terraform-State-Datei ist von entscheidender Bedeutung. Die State-Datei ist unter anderem zuständig für:

  • eine Repräsentation der tatsächlichen Infrastruktur zur Berechnung des Ausführungsplans (Vorschau der Änderungen vor dem Übernehmen)
  • die Kontrolle gleichzeitiger Ausführungen, wenn sie in einem remote State Backend wie einem Azure Storage Account gespeichert sind

Die State-Datei ist die Grundlage für einige der beliebtesten Terraform-Funktionen. Dies ist jedoch häufig der Grund, warum Teams Konfigurationsdrifts in Terraform beheben oder abgleichen müssen. Der Terraform-Zustand kann auch sensible Daten (z. B. Passwörter) enthalten und muss daher geschützt werden.

Sprachsyntax

 

Bicep und Terraform verfügen über dedizierte Sprachen, die Entwickler verwenden, um Infrastruktur als Code auszudrücken. Beide Sprachen sind deklarativ. Sie sind ziemlich ähnlich, teilweise auch gram­ma­ti­ka­lisch. Lassen Sie uns einige der Unterschiede, Stärken und Schwächen hervorheben:

Benutzerdefinierte Validierungen

Obwohl die zugrundeliegenden ARM-APIs jedes Objekt während des Deployments validieren, ist die Bereitstellung einer benutzerdefinierten Validierung in IaC-Projekten unerlässlich. Mit der benutzerdefinierten Validierung können Sie:

  • einfache Governance-Regeln erzwingen, bevor eine Bereitstellung die Azure Resource Manager API erreicht
  • Benutzereingaben anhand individueller Richtlinien validieren

Wie im ersten Code-Snippet zu sehen ist, basiert die benutzerdefinierte Validierung in Bicep auf einem Muster namens decorators. Parameter sind mit benutzerdefinierten Validierungsregeln ausgestattet. Benutzer können bei Bedarf mehrere decorators auf einem einzelnen Parameter anwenden:

 
				
					// sample.bicep

@minLength(5)
@allowed([
  'germanywestcentral'
  'eastus2'
  'westeurope'
])
param location string
				
			

Im Gegensatz dazu fühlt sich die benutzerdefinierte Validierung in Terraform wie eine kleine Makrosprache an. Validierungsregeln in Terraform können jede der integrierten Funktionen nutzen, um die Logik darzustellen:

				
					# sample.tf

variable "location" {
  type    = string
  validation {
    condition     = contains(["eastus2", "germanywestcentral", "westeurope"], var.location)
    error_message = "Please use one of the following regions (germanywestcentral|eastus2|westeurope)."
  }
}

				
			

Wenn ich mir beide – ziemlich einfache – Beispiele ansehe, bevorzuge ich die benutzerdefinierte Validierungssyntax von Bicep. Sie ist leicht zu merken und fühlt sich fokussierter an. Die Verkettung verschiedener decorators fühlt sich für eine deklarative Sprache natürlicher an.

Festlegen der Ressourcenversion

Azure Services entwickeln sich weiter. Ständige Verbesserungen können dazu führen, dass neue ARM-API-Versionen veröffentlicht werden. Der azurerm-Anbieter in Terraform basiert auf der neuesten API-Version. Entwickler möchten jedoch möglicherweise eine alte Version des Anbieters verwenden, wenn sie nach einer bestimmten Version für einen bestimmten Azure Service suchen. Dies kann jedoch dazu führen, dass auch ältere API-Versionen für andere Azure-Ressourcen verwendet werden. Daher müssen Entwickler bei der Beschreibung einer bestimmten Ressource die API-Version nicht angeben, wie hier gezeigt:

				
					# sample.tf

resource "azurerm_container_registry" "acr" {
  name                     = "thorstenhans"
  resource_group_name      = azurerm_resource_group.rg.name
  location                 = var.location
  sku                      = "Standard"
}
				
			

Im Gegensatz dazu enthalten Typbezeichner in Bicep die Versionsnummer, wenn mehrere Versionen verfügbar sind. Um dieselbe Azure Container Registry (ACR) in Bicep mit der neuesten API-Vorschauversion bereitzustellen, ist der folgende Code erforderlich:

				
					// sample.bicep

resource acr 'Microsoft.ContainerRegistry/registries@2020-11-01-preview' = {
    name: 'thorstenhans'
    location: location
    sku: {
        name: 'Standard'
    }
}
				
			

Ich würde gerne die Versionsspezifikation @2020-11-01-preview loswerden. Über einen Hinweis auf die neueste Version würde ich mich freuen. Zum Beispiel so etwas wie Microsoft.ContainerRegistry/registries oder Microsoft.ContainerRegistry/registries@latest, die auf die aktuelle Version zeigt.

Bedingte Bereitstellungen

Konditionale Bereitstellungen sind in IaC oft erforderlich. Benutzer möchten beispielsweise unterstützende Dienste nur für Staging- oder Produktionsumgebungen bereitstellen, sie jedoch für die Entwicklungsumgebung ignorieren, um Kosten zu senken oder vorhandene Services in der Entwicklung wiederzuverwenden. Bicep und Terraform verwenden eine leicht unterschiedliche Syntax, um konditionale Ressourcenbereitstellungen zu unterstützen.

In Bicep wird der Ressourcendeklaration ein konditionaler Ausdruck mit dem Schlüsselwort if hinzugefügt, wie hier gezeigt:

				
					// sample.bicep

param is_dev bool

resource ai 'Microsoft.Insights/components@2020-02-02-preview' = if (!is_dev) {
  name: 'ai-test'
  kind: 'web'
  location: 'westeurope'
}
				
			

Im Gegensatz dazu verwendet Terraform die Eigenschaft count – diese ist für jede Ressource verfügbar, um konditionale Bereitstellungen zu unterstützen:

				
					# sample.tf

variable "is_dev" {
    type = bool
}

resource "azurerm_application_insights" ai {
  name                  = "thns-demo"
  resource_group_name   = "tf-sample"
  location              = "germanywestcentral"
  application_type      = "web"
  count                 = var.is_dev ? 0 : 1
}
				
			

Vergleicht man beide Ausschnitte, merkt man schnell, dass Bicep hier im Vorteil ist. Bedingungen in Bicep fühlen sich einfacher an im Vergleich zu Terraform.

Tooling

Robuste und effiziente Tools sind für viele Entwickler (einschließlich mir) sehr wichtig. In diesem Abschnitt werden wir verschiedene Aspekte im Kontext des Toolings betrachten, wie zum Beispiel:

  • Produktivität des Command Line Interface (CLI)
  • Codierungsunterstützung und IDE-Integration
  • Importieren vorhandener ARM-Templates, um ein Projekt zu starten

Command Line Interfaces

Terraform CLI ist genial. Es läuft fast überall, ist einfach zu installieren (nur eine Binärdatei), und ist super robust. Terraform CLI ist ein Arbeitstier, das nur einen Zweck hat: Ihnen zu helfen, Ihre Aufgaben zu erledigen.

Einige der bekanntesten Terraform-CLI-Befehle sind:

  • terraform init – ein Terraform-Projekt initialisieren und alle erforderlichen Anbieter installieren
  • terraform plan – Vorschau der Änderungen, bevor die zugrundeliegende Cloud-Infrastruktur geändert wird
  • terraform apply – aktuelle Konfiguration anwenden
  • terraform fmt – alle .tf-Dateien im aktuellen Ordner neu formatieren
  • terraform validate – Terraform-Projekt validieren

Bicep lässt sich in Azure CLI integrieren, was ebenfalls erstaunlich ist. Ich liebe az und benutze es jeden Tag. Die Auslieferung von Bicep als Erweiterung für Azure CLI war offensichtlich und besser, als es von Grund auf neu zu erstellen – mit sagen wir mal Node.js. Die Bicep CLI bietet nur eine Handvoll Unterbefehle. Vielleicht, weil Bicep noch relativ neu ist, vielleicht weil es bestehende Mechanismen und Muster nutzt, die sich für den Umgang mit ARM-Templates etabliert haben.

Die wichtigsten az-Befehle im Kontext von Bicep sind:

  • az bicep build – Transpilieren einer oder mehrerer Bicep-Dateien in ein ARM-Template
  • az bicep decompile – ARM-Template nach Bicep dekompilieren
  • az bicep upgrade – Bicep CLI aktualisieren
  • az deployment group create – Bereitstellen im Bereich der Azure-Ressourcengruppe
  • az deployment sub create – Bereitstellen im Azure-Abonnementbereich

Ich würde gerne einen dedizierten format oder fmt Unterbefehl für den Bicep CLI mit entsprechenden Markierungen wie --check sehen. Ich verwende die von Terraform bereitgestellten Befehle (terraform fmt --check) in CI/CD, um das richtige Styling sicherzustellen.

Bicep-Ausführungsplan (Vorschau der Änderungen) Die Vorschau von Änderungen vor dem Modifizieren zugrundeliegender Cloud-Infrastrukturen ist vielleicht der prominenteste USP von Terraform. Sowohl Azure CLI als auch Azure PowerShell bieten ähnliche Funktionen mithilfe der what-if Befehle, wie unten gezeigt:

				
					# create a new Resource Group
az group create -n testgr -l germanywestcentral

# compile Bicep to ARM Template
az bicep build -f myinfra.bicep

# preview potential changes
az deployment group what-if -g testgr -f myinfra.json
				
			

Vorschau von Änderungen mit dem what-if Befehl

Codierungsunterstützung und IDE-Integration

Es gibt Visual Studio Code-Erweiterungen für beide Sprachen. Beide verwenden einen zugrundeliegenden Sprachdienst, um Codevervollständigung und umfassende IntelliSense-Funktionen anzubieten.

Die offizielle Terraform-Erweiterung für VSCode ist einigermaßen okay. Abhängig von der Komplexität Ihres Infrastrukturprojekts kann es von Zeit zu Zeit zu einer Unterbrechung von IntelliSense kommen. Verweise auf resourcesvariables und locals werden irgendwann nicht mehr funktionieren. Zumindest erlebe ich das so hin und wieder in verschiedenen Umgebungen.

Terraform-Erweiterung für Visual Studio Code – defekter IntelliSense

Obwohl Bicep so neu ist, übertrifft dessen Codierungsunterstützung bereits die von Terraform. Der Verweis auf vorhandene Elemente, die automatische Vervollständigung und die Validierung funktionieren für mich ausgezeichnet. Zumindest solange die gesamte Infrastruktur zu einer einzigen Datei gehört.

Bicep-Erweiterungen für Visual Studio Code

Eine gute Codevervollständigung und reichhaltiges IntelliSense zu erhalten ist mitunter geschäftskritisch. Sobald die Leute die Sprachgrundlagen verstanden haben, suchen sie immer nach großartigen Werkzeugen, um ihre Produktivität zu steigern. Die Tools von Visual Studio Code sind ein Bereich, in dem Terraform sich in Zukunft verbessern könnte und sollte.

Vorhandene ARM-Vorlagen importieren

Viele Teams verfügen über vorhandene ARM-Vorlagen zum Migrieren oder Importieren in Tools wie Terraform oder Bicep. Beide Tools bieten einen Mechanismus zum Importieren vorhandener ARM-Vorlagen. Es gibt jedoch grundlegende Unterschiede.

Bicep CLI wird mit dem praktischen Befehl decompile geliefert. Es nimmt ein vorhandenes ARM-Template (mehrere JSON-Vorlagendateien werden unterstützt) und versucht, sie in .bicep zu dekompilieren.

Ich habe az bicep decompile mit ein paar (ziemlich einfachen) ARM-Templates getestet und es hat für mich gut funktioniert. Als ich aber versuchte, komplexere Infrastrukturen zu dekompilieren, traten einige Fehler auf und die resultierende Bicep-Datei war ungültig. Ich bin mir allerdings sicher, dass sich das Tool in diesem Bereich im Laufe der Zeit verbessern wird. Es lohnt sich zumindest, es hin und wieder auszuprobieren.

Terraform verfolgt einen anderen Ansatz in Bezug auf bereits vorhandene ARM-Templates. Terraform behandelt ein gesamtes ARM-Template als atomare Ressource. Obwohl dies zunächst praktisch erscheint, fehlt es an der Möglichkeit, feingranulare Modifikationen vorzunehmen.

Es gibt jedoch mehrere Open-Source-Tools, die versuchen, die Übersetzung von ARM-Templates in die Sprache Terraform (früher bekannt als HashiCorp Configuration Language) anzugehen. Ich habe jedoch festgestellt, dass diese Tools oft auf älteren Versionen von Terraform-Providern wie azurerm basieren, was zu Inkompatibilitäten führt.

Zusammenfassung

Die Bicep-Sprache ist großartig und ihre Tools sind robust. Im Vergleich zu Terraform könnten Entwickler bei Parametern und deren Validierungslogik schneller werden. Bicep ist natürlich darauf ausgelegt, Azure-Infrastrukturen bereitzustellen. In Multi-Cloud-Szenarien ist Terraform immer noch die beste Option.

Apropos dedizierte Azure-Infrastrukturen: Bicep ist aufgrund der makellosen Integration mit der zugrundeliegenden Azure Resource Manager API die bevorzugte Lösung.

Letztendlich würde ich Ihnen raten, das Tool nach den tatsächlichen Anforderungen auszuwählen. Für alles, was nur mit Azure zu tun hat, werde ich Bicep verwenden. Viele unserer Kunden sind aber mit Terraform glücklich, und zufrieden. Ihre Projekte wachsen weiter und benötigen von Zeit zu Zeit ein bisschen Wartung. Trotzdem gibt es genug Platz für Terraform und Bicep – zumindest in meinem Werkzeuggürtel.

Kostenloser
Newsletter

Aktuelle Artikel, Screencasts, Webinare und Interviews unserer Experten für Sie

Verpassen Sie keine Inhalte zu Angular, .NET Core, Blazor, Azure und Kubernetes und melden Sie sich zu unserem kostenlosen monatlichen Dev-Newsletter an.

Newsletter Anmeldung
Diese Artikel könnten Sie interessieren
Cloud Native
favicon

Cloud Security: The 4C’s Of Cloud-Native Security – Part 5

In the last part of the article series on the 4C's of cloud-native security, we will look at securing the cloud environment itself. Although actual steps to harden your cloud infrastructure differ based on the cloud vendor and the services used to architecture your cloud-native application, many concepts and methodologies are quite similar.
14.04.2022
Cloud Native
favicon

Code Security: The 4C’s Of Cloud-Native Security – Part 4

In this part of the article series on the 4C's of cloud-native security, we will take a closer look at code security. We will briefly inspect why code security is essential, why it should be addressed from the beginning, and why trends such as shift-left security are important aspects of overall security considerations.
18.03.2022
Cloud Native
favicon

Cluster Security: The 4C’s Of Cloud-Native Security – Part 3

Securing the Kubernetes cluster (which may act as a runtime platform for several components of typical cloud-native applications) addresses one of the 4C's in cloud-native security. If you haven't heard about the 4C's of cloud-native security yet or want a quick refresher, you should read my corresponding introduction article.
04.03.2022
Cloud Native
favicon

Container Security: The 4C’s Of Cloud-Native Security – Part 2

Securing the container images of your cloud-native application building blocks addresses one of the 4C's in cloud-native security. If you haven't heard about the 4C's of cloud-native security yet or want a quick refresher, you should read my corresponding introduction post.
24.02.2022
Cloud Native
favicon

Code, Container, Cluster, Cloud: The 4C’s Of Cloud-Native Security – Part 1

Containers and cloud-native design patterns gained popularity over the past years. More and more organizations use containers in production and adopt cloud-native practices and methodologies to get even more value from existing containerized applications and underlying technologies such as container orchestrators like Kubernetes.
15.02.2022
Cloud Native
favicon

Ausführen von Containern in Azure Container Instances (ACI) direkt über die Docker CLI

Vor einigen Monaten haben sowohl Microsoft als auch Docker eine nahtlose Integration von Azure Container Instances (ACI) und Docker CLI angekündigt. Als Container-Enthusiast musste ich mich natürlich mit dieser Integration befassen. Ich habe es in verschiedenen Szenarien getestet, um zu sehen, wie es mich unterstützen und meine Produktivität steigern könnte.
05.11.2021