Wir lassen die Muskeln spielen

Wir lassen die Muskeln spielen

95 % der Anwendungen, die wir entwickeln, laufen mittlerweile in der Cloud, genauer gesagt in Azure. Das bietet uns und unseren Kund:innen viele Vorteile:

Viel höhere Sicherheit, als bei einem lokalen Server jemals möglich wäre, schnellere Entwicklungszyklen, mächtige Werkzeuge und natürlich die Möglichkeit, die Infrastruktur genau an den Bedarf der Anwendungen anzupassen:

Ist die Software nur tagsüber in Betrieb? Kein Problem, dann fahren wir die Server nachts herunter und sparen so Betriebskosten.
Sind in den nächsten Tagen Auslastungsspitzen zu erwarten? Okay, dann nutzen wir genau für den Zeitraum ein paar zusätzliche Server.

Damit so eine dynamische Skalierung reibungslos funktioniert, muss eine Software allerdings auch von Beginn an darauf ausgelegt sein, was eine gewisse Komplexität mit sich bringt:
Wenn z.B. die Möglichkeit besteht, dass die Anwendung auf mehreren Servern gleichzeitig läuft, können Bilder oder Dokumente nicht einfach im Dateisystem des Servers abgespeichert werden, sondern müssen in einem externen Speicher abgelegt werden. Daneben gibt es meist zumindest noch eine Datenbank und je nach Projekt verschiedene weitere Systeme. Eine typische sogenannte „cloud-native“ Anwendung umfasst also mehrere Komponenten (sogenannte Ressourcen), die alle korrekt miteinander „verdrahtet“ werden müssen.

Handarbeit

Die einfachste Möglichkeit, eine Ressource in Azure zu erstellen, ist mittels der Benutzeroberfläche des entsprechenden Portals (Abbildung 1). Mit wenigen Klicks lassen sich hier Datenbanken, Web-Server & Co einrichten und konfigurieren. Diese Vorgehensweise mag zwar auf den ersten Blick schnell und einfach wirken, hat jedoch auch einige Nachteile:

  • Nachvollziehbarkeit: Änderungen sind später nicht oder nur schwer nachzuvollziehen: Wer hat wann warum welche Konfigurationseinstellungen vorgenommen?
  • Konsistenz: Die ad-hoc-Vorgehensweise führt beinahe zwangsläufig zu verschiedenen Schreibweisen bei der Benennung.
  • Wiederholbarkeit: Soll eine weitere Kopie der Anwendung zur Verfügung gestellt werden, z.B. für ein (zusätzliches) Entwicklungssystem, für Last- oder Security-Tests, die Produktivumgebung, etc., geht das nur durch mühsames manuelles Nachbauen.
Manuelles Erstellen einer Web-Anwendung über die Benutzeroberfläche'
Abbildung 1: Manuelles Erstellen einer Web-Anwendung über die Benutzeroberfläche

Infrastructure as Code

Besser ist es daher, die Infrastruktur-Komponenten einer Anwendung automatisiert zu erstellen. Man „programmiert“ also nicht nur den Anwendungscode, sondern auch die Erzeugung der benötigten Infrastruktur – daher der Name „Infrastructure as Code“ oder kurz „IaC“.

Diese Vorgehensweise hat folgende Vorteile:

  • Versionierung: Der IaC-Code kann ebenso wie der Anwendungscode in die Versionsverwaltung eingecheckt werden. Dadurch sind sämtliche Änderungen nachvollziehbar und alte Versionen können jederzeit wiederhergestellt werden.
  • Dokumentation: Der IaC-Code dient gleichzeitig als Dokumentation der Architektur, weil auf einen Blick ersichtlich ist, welche Komponenten es gibt und wie sie zusammenspielen.
  • Wiederverwendbarkeit: Die Erzeugung der verschiedenen Komponenten kann modular gestaltet und so leicht projektübergreifend wiederverwendet werden. Einzelne Teammitglieder können sich auf die Konfiguration spezialisieren und sinnvolle Einstellungen vorschlagen.
  • Konsistenz: Durch die Wiederverwendung der Templates ist auch die Konsistenz hinsichtlich Namensgebung und Konfiguration über mehrere Projekte hinweg einheitlich. Das hilft Entwickler:innen, sich in neuen Projekten schnell zurecht zu finden.
  • Effizienz: Darüber hinaus ist es natürlich auch effizienter, wenn man ein Setup aus einem anderen Projekt einfach übernehmen kann, anstatt wieder bei 0 mit der manuellen Konfiguration zu beginnen.
  • Wiederholbarkeit: Neue Umgebungen lassen sich mit IaC auf Knopfdruck in Minuten erstellen. Damit lassen sich auch Fehler vermeiden, die auf unterschiedliche Einstellungen in Entwicklungs- und Produktivsystem zurückzuführen sind.

Es gibt verschiedene technische Möglichkeiten, IaC zu implementieren. Die Basis dafür bildet in Azure eine REST-Schnittstelle. Diese kann entweder direkt, über die Azure Command Line oder über PowerShell aufgerufen werden. Dabei muss man jedoch imperativ vorgehen, die Ressourcen also nacheinander und in der richtigen Reihenfolge erzeugen.

Besser deklarativ

Sogenannte ARM-Templates (für Azure Resource Manager) stellen im Gegensatz dazu einen deklarativen Ansatz dar. Man beschreibt also nicht im Detail, wie die einzelnen Ressourcen zu erstellen sind, sondern nur, was man alles benötigt – also den Zielzustand. Der Azure Resource Manager kümmert sich dann darum, diesen Zustand herzustellen – egal, ob dazu neue Komponenten erstellt oder bestehende anders konfiguriert werden müssen.

Bei den ARM-Templates handelt es sich um ein JSON-basiertes Dateiformat, in dem die benötigten Ressourcen und ihre Einstellungen beschrieben werden. Das Format ist somit (zumindest theoretisch) nicht nur für Maschinen, sondern auch für Menschen einigermaßen gut lesbar. In der Praxis zeigt sich leider, dass das nur bedingt zutrifft. Die Syntax ist teilweise recht umständlich und beinhaltet viele Sonderzeichen, manche Dinge lassen sich darüber hinaus in der JSON-Struktur nicht besonders gut abbilden.

Erstellen einer Web-Anwendung mittels ARM-Template
Abbildung 2: Erstellen einer Web-Anwendung mittels ARM-Template

Was ist jetzt also der Königsweg?

Hier kommt nun endlich das titelgebende Bicep-Format in Spiel.

Bicep (zu Deutsch: Bizeps; sozusagen eine stärkere Version der ARM-Templates) ist eine sogenannte domänen-spezifische Sprache. Es ist also eine (Programmier-) Sprache, die für einen speziellen Zweck – nämlich die Definition von Azure-Ressourcen – optimiert wurde.
Im Gegensatz zu den ARM-Templates, die auf das allgemeine JSON-Format setzen, gibt es hier eigene Konstrukte, die das Anlegen der verschiedenen Komponenten auf einfache Art und Weise ermöglichen. So können etwa Schleifen genutzt werden, um wiederkehrende Aufgaben durchzuführen. Die Syntax ist merkbar entschlackt (siehe Abbildung 3) und bietet alle Komfortfunktionen, die man sich als Entwickler:in wünscht (Syntax-Highlighting, Auto-Complete, …).

Erstellen einer Web-Anwendung mit Bicep
Abbildung 3: Erstellen einer Web-Anwendung mit Bicep

Fazit

Bei allen Vorteilen bringen Cloud-Anwendungen auch eine gewisse Komplexität mit sich. Für einfache Projekte mag es zu Beginn ausreichen und sogar schneller sein, die notwendigen Ressourcen manuell anzulegen – sobald es etwas umfangreicher wird, setzen wir aber auf jeden Fall auf Infrastructure as Code.

Dank einer mittlerweile umfangreichen Bibliothek von wiederverwendbaren Bicep-Templates können wir ohne großen Aufwand von den diversen Vorteilen, von Nachvollziehbarkeit über Konsistenz bis hin zu Zeitersparnis, profitieren.