Vorbei die Zeiten, in denen händisch Infrastruktur aufgebaut wurde. Mit Infrastructure as Code lässt sich die Cloud-Infrastruktur auf einfache Weise deklarativ beschreiben. Leider allzu oft in Form von großen YAML- oder JSON-Dokumenten. Wir schauen in diesem Artikel, welche Alternativen es gibt und wann sie sich lohnen.
Alle großen Cloud-Provider wie etwa Google, Microsoft oder Amazon bieten eigene YAML/JSON-Formate für Infrastructure as Code (IaC) an. Die Infrastruktur wird deklarativ beschrieben und vom Cloud-Provider dementsprechend erstellt. Die Beschreibung kann beliebige Cloud-Ressourcen, wie etwa Maschinen, Datenbanken oder Load Balancer inklusive Beziehungen zwischen diesen, enthalten.
Wer jedoch einmal eine aufwändige Infrastruktur mit YAML/JSON beschrieben hat, weiß, dass so eine Beschreibung schnell groß und unübersichtlich wird. Verschiedene Werkzeuge (z.B. Schema-Validatoren) oder Entwicklungsumgebungen helfen zwar, aber dennoch gerät die Beschreibung bei aufwendiger Infrastruktur schnell an die Grenzen der Wartbarkeit. Der Grund: Es gibt keine Möglichkeit, eigene Abstraktionen zu erstellen.
Listing 1 zeigt ein Beispiel, in dem drei S3-Buckets für die Länder der DACH-Region angelegt werden, teilweise mit unterschiedlicher Konfiguration. Sobald weitere Länder hinzugefügt werden, wird das Dokument unverhältnismäßig groß. Es fehlt das Mittel der Abstraktion, um diese Redundanzen zu vermeiden.
Die Redundanz könnte durch den Einsatz einer geeigneten Abstraktion reduziert werden. Statt jeden Bucket einzeln zu beschreiben, könnte eine Abstraktion, Country-Bucket, helfen. Diese definiert eine feste Namenskonvention und erlaubt nur die Konfiguration der Versionierung. Alle anderen Details werden durch die Abstraktion versteckt.
Um die fehlende Flexibilität von YAML/JSON auszugleichen, bieten Template-Sprachen wie Jsonnet oder Cue Abhilfe. Diese erweitern YAML/JSON um zusätzliche Funktionalität. Durch Funktionen und Variablen lassen sich so Abstraktionen entwickeln, die das Beschreiben von Infrastruktur deutlich kompakter und übersichtlicher gestalten. Anders als gewöhnliche Template-Engines sind Jsonnet und Cue zudem bewusst zur Erstellung von YAML/JSON und ähnlichen strukturierten Formaten gedacht.
Listing 2 zeigt den Einsatz von Jsonnet. Durch die Abstraktion Country-Bucket gestaltet sich das Dokument deutlich schmaler, erzeugt aber weithin dasselbe Resultat. Neue Länder können übersichtlich hinzugefügt werden. Ändert sich die Definition eines Country-Buckets, gibt es eine zentrale Stelle, die angepasst werden kann.
Der Einsatz von Jsonnet und Cue lohnt sich vor allem dann, wenn die Nähe zum Zielformat (z.B. CloudFormation) erhalten bleiben soll, gezielte Abstraktionen für die Verständlichkeit jedoch unabdingbar sind. Lediglich ein zusätzlicher Schritt zur Generierung des Zielformats muss in Kauf genommen werden.
Natürlich beschränken sich Abstraktionen nicht nur auf einzelne Cloud-Ressourcen. Auch das Kombinieren verschiedener Ressourcen zu einer logischen Einheit ist sinnvoll. Besteht die Infrastruktur etwa aus vielen verschiedenen Services, könnte eine Abstraktion, die mehrere Maschinen, eine Datenbank sowie Load Balancing umfasst, enorme Mehrwerte bringen. Das gilt insbesondere dann, wenn diese logische Einheit mehrfach zum Einsatz kommt.
In eine andere Richtung bewegt sich Terraform, das wohl verbreitetste Werkzeug im Bereich Infrastructure as Code. Statt YAML/JSON kommt eine eigens entwickelte Sprache zum Einsatz. Cloud-Ressourcen und Beziehungen zwischen diesen können explizit mit dafür vorgesehenen Konstrukten beschrieben werden. Auch aufwendige Abstraktionen lassen sich mit Terraform einfach realisieren und sind durch das Modulsystem ein bewusster Bestandteil. Zusätzlich bietet die Community bereits viele fertige Abstraktionen in Form wiederverwendbarer Module an.
Listing 3 zeigt ein Beispiel mit Terraform, das mithilfe eines wiederverwendbaren CountryBucket-Moduls drei S3-Buckets erstellt. Zusätzlich werden über den Mechanismus for_each drei Buckets mit unterschiedlichen Parametern erzeugt, ohne diese einzeln auflisten zu müssen. Um neue Länder hinzuzufügen, muss lediglich die lokale Variable countries angepasst werden.
Terraform ist im Bereich Infrastructure as Code stets eine gute Wahl, eine neue Sprache zu erlernen, kann jedoch einen Nachteil gegenüber den JSON/YAML-basierten Ansätzen der Cloud-Provider darstellen. Für komplexe Abstraktionen, die über Projektgrenzen hinweg zwischen verschiedenen Teams geteilt werden sollen, ist Terraform durch den modularen Aufbau indessen eine gute Wahl. Zusätzlich ermöglicht die Beschreibung von Infrastruktur im Multi-Cloud-Bereich, da Terraform alle großen Cloud-Provider unterstützt.
Zwar lässt sich mit Template-Sprachen und Werkzeugen wie Terraform die Infrastruktur bereits sehr übersichtlich beschreiben, dennoch zeigen sich bei Umsetzung komplexer Abstraktionen schnell Grenzen auf. Ein möglicher Ansatz, um diese zu überwinden, bieten programmatische Ansätze wie Pulumi oder das AWS Cloud Development Kit (CDK). Statt auf YAML/JSON oder eigene Sprachen zu setzen, steht bewusst die Verwendung von Allzwecksprachen im Fokus. Die Beschreibung erfolgt hier in bekannten Sprachen wie TypeScript, Java oder C#.
Cloud-Ressourcen werden hier als Objekte im Sinne der objektorientierten Programmierung abgebildet. Diese können, wie in der Softwareentwicklung üblich, zusammengesteckt werden, um komplexe Logik abzubilden. Aufwändige Abstraktionen lassen sich somit deutlich besser realisieren. Während der Aufbau der Objekte zwar imperativ erscheint, ist das Ergebnis weiterhin eine deklarative Beschreibung der Infrastruktur und hebt sich damit immer noch von händischen Aufrufen der APIs von Cloud-Anbietern ab.
Listing 4 zeigt ein Beispiel für eine CDK-Anwendung. Mithilfe einer TypeScript-Funktion wird eine Abstraktion für den Country-Bucket definiert. Zusätzlich werden Funktionen aus der Standardbibliothek verwendet. Das gesamte TypeScript-Ökosystem steht bei der Beschreibung der Infrastruktur zur Verfügung.
Die programmatische Beschreibung der Infrastruktur mit Pulumi, CDK und ähnlichen Werkzeugen bietet sich an, wenn komplexe Abstraktionen benötigt werden, die sich nur schwer mit anderen Ansätzen umsetzen ließen. Also genau dann, wenn die volle Funktionalität einer Allzwecksprache notwendig ist.
Ein weiterer Vorteil ist, dass sich gängige Praktiken der Softwareentwicklung somit auf Infrastruktur anwenden lassen. Unit-Testing, Qualitätssicherung etc. können mit bekannten Werkzeugen umgesetzt werden. Die Flexibilität kann jedoch auch schnell zu unverständlicher Infrastruktur führen. Es fordert eine gewisse Disziplin, die Infrastruktur weitestgehend deklarativ zu gestalten, wenn dies nicht durch die verwendete Sprache forciert wird. Hier gilt immer abzuwägen, ob die Flexibilität auch tatsächlich benötigt wird.
Da sich dieser Ansatz großer Beliebigkeit erfreut, gibt es inzwischen mit Terraform CDK und cdk8s auch Varianten für Terraform und Kubernetes-Resourcen.
Alle großen Cloud-Provider bieten ein YAML/JSON-basiertes Format zur Beschreibung der gewünschten Infrastruktur an. Für einfache Fälle bieten diese Formate bereits eine gute Grundlage zur Bereitstellung der eigenen Infrastruktur. Sobald diese jedoch komplexer wird, ist die Möglichkeit, eigene Abstraktionen zu erstellen, unabdingbar. Andernfalls droht die Gefahr einer nicht wartbaren Infrastruktur.
Die von den Cloud-Providern angebotenen Formate sollten daher nur in einfachsten Fällen verwendet werden. Ist die Nähe zum Zielformat wichtig, etwa um von Beispielen und Dokumentationen zu profitieren, lohnen sich Template-Sprachen wie Jsonnet oder Cue. Besteht der Bedarf nach reichhaltigen Abstraktionen, sind programmatische Lösungen wie Pulumi oder CDK sinnvoll. Für alle anderen Fälle bietet Terraform einen guten Kompromiss zwischen Flexibilität und Wartbarkeit. So oder so: Ein YAML-Experte ist also nicht zwingend notwendig, um Infrastructure as Code umzusetzen.
In den kommenden Wochen und Monaten erscheinen weitere Artikel zum Thema Cloud.
Weitere Artikel der Serie:
Was ist eigentlich aus Serverless geworden?
Der Artikel ist Teil der IT Spektrum 06/22 S. 49
Die Vorschau des Magazins ist hier zu finden.
Alle großen Cloud-Provider wie etwa Google, Microsoft oder Amazon bieten eigene YAML/JSON-Formate für Infrastructure as Code (IaC) an. Die Infrastruktur wird deklarativ beschrieben und vom Cloud-Provider dementsprechend erstellt. Die Beschreibung kann beliebige Cloud-Ressourcen, wie etwa Maschinen, Datenbanken oder Load Balancer inklusive Beziehungen zwischen diesen, enthalten.
Wer jedoch einmal eine aufwändige Infrastruktur mit YAML/JSON beschrieben hat, weiß, dass so eine Beschreibung schnell groß und unübersichtlich wird. Verschiedene Werkzeuge (z.B. Schema-Validatoren) oder Entwicklungsumgebungen helfen zwar, aber dennoch gerät die Beschreibung bei aufwendiger Infrastruktur schnell an die Grenzen der Wartbarkeit. Der Grund: Es gibt keine Möglichkeit, eigene Abstraktionen zu erstellen.
Listing 1 zeigt ein Beispiel, in dem drei S3-Buckets für die Länder der DACH-Region angelegt werden, teilweise mit unterschiedlicher Konfiguration. Sobald weitere Länder hinzugefügt werden, wird das Dokument unverhältnismäßig groß. Es fehlt das Mittel der Abstraktion, um diese Redundanzen zu vermeiden.
Die Redundanz könnte durch den Einsatz einer geeigneten Abstraktion reduziert werden. Statt jeden Bucket einzeln zu beschreiben, könnte eine Abstraktion, Country-Bucket, helfen. Diese definiert eine feste Namenskonvention und erlaubt nur die Konfiguration der Versionierung. Alle anderen Details werden durch die Abstraktion versteckt.
Um die fehlende Flexibilität von YAML/JSON auszugleichen, bieten Template-Sprachen wie Jsonnet oder Cue Abhilfe. Diese erweitern YAML/JSON um zusätzliche Funktionalität. Durch Funktionen und Variablen lassen sich so Abstraktionen entwickeln, die das Beschreiben von Infrastruktur deutlich kompakter und übersichtlicher gestalten. Anders als gewöhnliche Template-Engines sind Jsonnet und Cue zudem bewusst zur Erstellung von YAML/JSON und ähnlichen strukturierten Formaten gedacht.
Listing 2 zeigt den Einsatz von Jsonnet. Durch die Abstraktion Country-Bucket gestaltet sich das Dokument deutlich schmaler, erzeugt aber weithin dasselbe Resultat. Neue Länder können übersichtlich hinzugefügt werden. Ändert sich die Definition eines Country-Buckets, gibt es eine zentrale Stelle, die angepasst werden kann.
Der Einsatz von Jsonnet und Cue lohnt sich vor allem dann, wenn die Nähe zum Zielformat (z.B. CloudFormation) erhalten bleiben soll, gezielte Abstraktionen für die Verständlichkeit jedoch unabdingbar sind. Lediglich ein zusätzlicher Schritt zur Generierung des Zielformats muss in Kauf genommen werden.
Natürlich beschränken sich Abstraktionen nicht nur auf einzelne Cloud-Ressourcen. Auch das Kombinieren verschiedener Ressourcen zu einer logischen Einheit ist sinnvoll. Besteht die Infrastruktur etwa aus vielen verschiedenen Services, könnte eine Abstraktion, die mehrere Maschinen, eine Datenbank sowie Load Balancing umfasst, enorme Mehrwerte bringen. Das gilt insbesondere dann, wenn diese logische Einheit mehrfach zum Einsatz kommt.
In eine andere Richtung bewegt sich Terraform, das wohl verbreitetste Werkzeug im Bereich Infrastructure as Code. Statt YAML/JSON kommt eine eigens entwickelte Sprache zum Einsatz. Cloud-Ressourcen und Beziehungen zwischen diesen können explizit mit dafür vorgesehenen Konstrukten beschrieben werden. Auch aufwendige Abstraktionen lassen sich mit Terraform einfach realisieren und sind durch das Modulsystem ein bewusster Bestandteil. Zusätzlich bietet die Community bereits viele fertige Abstraktionen in Form wiederverwendbarer Module an.
Listing 3 zeigt ein Beispiel mit Terraform, das mithilfe eines wiederverwendbaren CountryBucket-Moduls drei S3-Buckets erstellt. Zusätzlich werden über den Mechanismus for_each drei Buckets mit unterschiedlichen Parametern erzeugt, ohne diese einzeln auflisten zu müssen. Um neue Länder hinzuzufügen, muss lediglich die lokale Variable countries angepasst werden.
Terraform ist im Bereich Infrastructure as Code stets eine gute Wahl, eine neue Sprache zu erlernen, kann jedoch einen Nachteil gegenüber den JSON/YAML-basierten Ansätzen der Cloud-Provider darstellen. Für komplexe Abstraktionen, die über Projektgrenzen hinweg zwischen verschiedenen Teams geteilt werden sollen, ist Terraform durch den modularen Aufbau indessen eine gute Wahl. Zusätzlich ermöglicht die Beschreibung von Infrastruktur im Multi-Cloud-Bereich, da Terraform alle großen Cloud-Provider unterstützt.
Zwar lässt sich mit Template-Sprachen und Werkzeugen wie Terraform die Infrastruktur bereits sehr übersichtlich beschreiben, dennoch zeigen sich bei Umsetzung komplexer Abstraktionen schnell Grenzen auf. Ein möglicher Ansatz, um diese zu überwinden, bieten programmatische Ansätze wie Pulumi oder das AWS Cloud Development Kit (CDK). Statt auf YAML/JSON oder eigene Sprachen zu setzen, steht bewusst die Verwendung von Allzwecksprachen im Fokus. Die Beschreibung erfolgt hier in bekannten Sprachen wie TypeScript, Java oder C#.
Cloud-Ressourcen werden hier als Objekte im Sinne der objektorientierten Programmierung abgebildet. Diese können, wie in der Softwareentwicklung üblich, zusammengesteckt werden, um komplexe Logik abzubilden. Aufwändige Abstraktionen lassen sich somit deutlich besser realisieren. Während der Aufbau der Objekte zwar imperativ erscheint, ist das Ergebnis weiterhin eine deklarative Beschreibung der Infrastruktur und hebt sich damit immer noch von händischen Aufrufen der APIs von Cloud-Anbietern ab.
Listing 4 zeigt ein Beispiel für eine CDK-Anwendung. Mithilfe einer TypeScript-Funktion wird eine Abstraktion für den Country-Bucket definiert. Zusätzlich werden Funktionen aus der Standardbibliothek verwendet. Das gesamte TypeScript-Ökosystem steht bei der Beschreibung der Infrastruktur zur Verfügung.
Die programmatische Beschreibung der Infrastruktur mit Pulumi, CDK und ähnlichen Werkzeugen bietet sich an, wenn komplexe Abstraktionen benötigt werden, die sich nur schwer mit anderen Ansätzen umsetzen ließen. Also genau dann, wenn die volle Funktionalität einer Allzwecksprache notwendig ist.
Ein weiterer Vorteil ist, dass sich gängige Praktiken der Softwareentwicklung somit auf Infrastruktur anwenden lassen. Unit-Testing, Qualitätssicherung etc. können mit bekannten Werkzeugen umgesetzt werden. Die Flexibilität kann jedoch auch schnell zu unverständlicher Infrastruktur führen. Es fordert eine gewisse Disziplin, die Infrastruktur weitestgehend deklarativ zu gestalten, wenn dies nicht durch die verwendete Sprache forciert wird. Hier gilt immer abzuwägen, ob die Flexibilität auch tatsächlich benötigt wird.
Da sich dieser Ansatz großer Beliebigkeit erfreut, gibt es inzwischen mit Terraform CDK und cdk8s auch Varianten für Terraform und Kubernetes-Resourcen.
Alle großen Cloud-Provider bieten ein YAML/JSON-basiertes Format zur Beschreibung der gewünschten Infrastruktur an. Für einfache Fälle bieten diese Formate bereits eine gute Grundlage zur Bereitstellung der eigenen Infrastruktur. Sobald diese jedoch komplexer wird, ist die Möglichkeit, eigene Abstraktionen zu erstellen, unabdingbar. Andernfalls droht die Gefahr einer nicht wartbaren Infrastruktur.
Die von den Cloud-Providern angebotenen Formate sollten daher nur in einfachsten Fällen verwendet werden. Ist die Nähe zum Zielformat wichtig, etwa um von Beispielen und Dokumentationen zu profitieren, lohnen sich Template-Sprachen wie Jsonnet oder Cue. Besteht der Bedarf nach reichhaltigen Abstraktionen, sind programmatische Lösungen wie Pulumi oder CDK sinnvoll. Für alle anderen Fälle bietet Terraform einen guten Kompromiss zwischen Flexibilität und Wartbarkeit. So oder so: Ein YAML-Experte ist also nicht zwingend notwendig, um Infrastructure as Code umzusetzen.
In den kommenden Wochen und Monaten erscheinen weitere Artikel zum Thema Cloud.
Weitere Artikel der Serie:
Was ist eigentlich aus Serverless geworden?
Der Artikel ist Teil der IT Spektrum 06/22 S. 49
Die Vorschau des Magazins ist hier zu finden.