CMS als Code

In „Infrastructure as Code: From the Iron Age to the Cloud Age“ beschreibt Kief Morris die „Eisenzeit“ als eine Zeit, in der „das Wachstum der Infrastruktur durch den Hardware-Einkaufszyklus begrenzt war. Da es Wochen dauern konnte, bis ein neuer Server ankam, gab es wenig Druck, schnell ein Betriebssystem darauf zu installieren und zu konfigurieren.“
Aber jetzt, im „Cloud-Zeitalter“, werden Systeme mithilfe von Cloud-Diensten bereitgestellt. Viele dieser Dienste, einschließlich Contentful, bieten benutzerfreundliche Nutzeroberflächen, mit denen Nutzer*innen Umgebungen konfigurieren können. Mit zunehmender Anzahl der Dienste, die von Teams betrieben werden, wird es leider unüberschaubar, jeden einzelnen Dienst zu warten, indem man auf die Nutzeroberfläche geht und sich durch sie klickt. „Infrastructure as Code“ ist ein Ansatz, um dieses Problem zu lösen: Die Konfiguration jedes Dienstes wird automatisiert und die Konfiguration wird zusammen mit dem Quellcode für die Anwendung in der Versionskontrolle gespeichert.
Monolithische CMS-Plattformen, die heute häufig verwendet werden, funktionieren nicht gut für Teams, die agile Entwicklungspraktiken wie „Infrastructure as Code“ und kontinuierliche Bereitstellung einsetzen. Die Bereitstellung, Migration und das Testen dieser Plattformen ist von Natur aus schwierig zu automatisieren.
Contentful hingegen ist eine Composable Content-Plattform, die für das Cloud-Zeitalter entwickelt wurde.
Kontinuierliche Bereitstellung
In der „Eisenzeit“ basierte die Softwareentwicklung auf der Idee der Boxed-Software, wobei neue Versionen einmal im Jahr oder sogar weniger oft veröffentlicht wurden. Teure und zeitaufwendige Release-Prozesse waren üblich, bei denen alles erstellt, dann alles getestet und dann alles so freigegeben wurde, wie es war.
Im Cloud-Zeitalter veröffentlichen agile Teams häufig, oft mehrmals pro Woche, sodass teure und zeitaufwendige Release-Prozesse nicht verwendet werden können, ohne dass die Bereitstellung zum Stillstand kommt. Aus diesem Grund haben viele agile Teams die kontinuierliche Bereitstellung eingeführt.
Teams, die Continuous Delivery einsetzen, verfügen über eine Bereitstellungspipeline, also eine Reihe von Validierungen, die eine neue Softwareversion auf ihrem Weg in die Produktion durchlaufen muss. Die Pipeline hat verschiedene Stufen, von denen jede ihre eigene Umgebung für die Ausführung der Software hat.

Stufe 1: Entwicklung
Dies geschieht oft auf den PCs der Entwickler*innen, auf denen sie neue Versionen der Software erstellen. Wenn Entwickler*innen eine neue Version bereitstellen möchten, übergeben sie ihren neuesten Code an ein Versionskontrollsystem und übertragen ihn in ein gemeinsames Repository. Dadurch wird die Pipeline initiiert.
Stufe 2: Build
Diese Stufe hängt von einem Build-Skript ab, das in der Lage ist, die laufende Version der Software aus dem Quellcode zu erstellen, Schritte wie das Installieren von Abhängigkeiten, das Kompilieren oder Transpilieren von Code durchzuführen und zu überprüfen, ob das Build-Skript erfolgreich ausgeführt wird.
Stufe 3: Test
Hier kommt es darauf an, ob automatisierte Tests verfügbar sind, um zu überprüfen, ob die Software wie erwartet funktioniert und ob neue Versionen keine Funktionalität beeinträchtigt haben, die in früheren Versionen funktioniert hat.
Stufe 4: QA
Entwickler*innen und QS-Abteilungen verwenden die Software und führen weitere Tests durch, um sicherzustellen, dass die Akzeptanzkriterien für die neuesten Änderungen erfüllt sind und die Software für die Produktion bereit ist.
Stufe 5: Bereitstellen
Die Software wird auf Produktionsserver hochgeladen. Die neue Version ist jetzt live.
Teams, die Contentful verwenden, können Umgebungen bereitstellen, Content migrieren und Tests mit APIs schreiben, sodass das Content-Management in agile Entwicklungspraktiken wie „Infrastructure as Code“ und „Continuous Delivery“ passt. So können Softwareentwicklungsteams qualitativ hochwertige Software erstellen und schnell bereitstellen.
Während die Einführung von Continuous Delivery einige Vorabinvestitionen und Änderungen in der Teamkultur erfordern kann, überwiegen die langfristigen Geschäftsvorteile alle damit verbundenen Probleme:
Schnellere Markteinführung: Kontinuierliche Bereitstellung erleichtert und fördert kürzere Lieferzyklen.
Verbesserte Engineering-Praktiken: Wenn das Unternehmen regelmäßigere Release-Zyklen verlangt, werden Technologieteams dazu angeregt, einen höheren Automatisierungsgrad zu nutzen und Praktiken wie die testgetriebene Entwicklung anzuwenden.
Reduziertes Risiko: Durch kleine und gezieltere Bereitstellungen ist es weniger wahrscheinlich, dass etwas schiefgeht als bei größeren und komplexeren Releases.
Der Release ist eine Geschäftsentscheidung: Wenn Entwicklerteams von der Komplexität der Bereitstellung entlastet werden, kann der Release einer neuen Funktion auch unabhängig von ihnen erfolgen, sodass die Geschäftsverantwortlichen den Knopf drücken können.
Offenlegung von Ineffizienzen: Ein kontinuierliches Bereitstellungssystem kann den Fokus von den Ineffizienzen in der Entwicklung auf die eigentlichen Probleme lenken, die diese verursachen, wie z. B. unklare Anforderungen.
Infrastruktur als Code
Damit die Software in jeder Umgebung ausgeführt werden kann, benötigt sie nicht nur den Quellcode für die Software, sondern auch die Infrastruktur, wie z. B. die Dienste und die zugehörigen Ressourcen, von denen sie abhängt. Ein gängiges Beispiel ist eine Datenbank. Wenn die Software eine Datenbank benötigt, muss für jede Umgebung eine bereitgestellt werden.
Viele Teams, die Software entwickeln, die auf Datenbanken angewiesen ist, sind mit dieser Situation vertraut. Sie haben Entwicklungs-, QA- und Produktionsdatenbanken mit Bereitstellungs- und Migrationsskripten eingerichtet. Diese Skripte können Datenbanken für das richtige Schema für die aktuelle Version der Software erstellen und sie von einer früheren Version auf die aktuelle Version aktualisieren. Die Skripte können auch tatsächliche Daten aktualisieren, wenn sich das Datenmodell so ändert, dass vorhandene Daten nach dem neuen Schema nicht mehr gültig sind. Schließlich erstellt das Team auch Integrationstests, die überprüfen, ob die Datenbank, das Schema und manchmal auch die Daten für die aktuelle Version der Software korrekt sind.
Dies gilt auch für Software as a Service (SaaS): Wenn die Software ein SaaS-Produkt verwendet, muss dieser Dienst für die jeweilige Umgebung verfügbar und konfiguriert sein. SaaS ist Infrastruktur, und um mit einer kontinuierlichen Bereitstellung zu arbeiten, muss SaaS als Code behandelt werden.
Contentful ermöglicht es Teams, Spaces zu erstellen, die wie Datenbanken für Content sind. Wie im obigen Beispiel für Datenbanken richten Teams häufig Entwicklungs-, QS- und Produktions-Spaces in Contentful ein.
Um eine Content-Infrastruktur für jede Umgebung in Ihrer Bereitstellungspipeline bereitzustellen, bieten Contentful-Spaces mehrere Space-Umgebungen. Sie haben Produktionsumgebungen, in denen Ihre Editor*innen und Autor*innen Ihren Produktionscontent pflegen und in denen Ihre Apps und Websites diesen Content abfragen, und mehrere Sandbox-Umgebungen, eine für jede Phase in Ihrer Bereitstellungspipeline. Umgebungen sind in jede Phase integriert, ähnlich wie Zweige in jedes Repository in Git integriert sind.
Pipelines und Workflows
Eine weitere Herausforderung für das Content-Management besteht darin, dass zwei Lebenszyklen gleichzeitig stattfinden, die beide Authoring, Verifizierung und Release erfordern: einer ist die Softwarebereitstellungspipeline und der andere ist der Workflow zur Content-Erstellung. Während Softwareentwickler-Teams Softwareversionen erstellen und veröffentlichen, erstellen und veröffentlichen Content-Ersteller*innen gleichzeitig Content.

Contentful bietet einen integrierten grundlegenden Workflow mit den Phasen „Entwurf“ und „Veröffentlicht“, die steuern, wann Content für Ihre Live-Systeme verfügbar ist, eine Vorschau-API, die für die Überprüfung von Content verwendet werden kann, sowie Funktionen, um Ihre eigenen, erweiterten Workflows zu erstellen. Die Content-Erstellung erfolgt nur in der Produktionsumgebung im Space von Kund*innen: Content-Ersteller*innen erstellen Entwürfe, die über die Vorschau-API überprüft und dann veröffentlicht werden. Andere Umgebungen, wie z. B. Dev oder QA, werden nur als Teil der Softwarebereitstellungspipeline verwendet.
Contentful bietet eine Composable Content-Plattform als Service, die als Code behandelt und in Ihre Bereitstellungspipeline aufgenommen werden kann. Um dies zu erreichen, benötigen Sie Bereitstellungsskripte, die eine Space-Umgebung mit Ihrem Content-Modell konfigurieren können, und Migrationsskripte, die eine Space-Umgebung von einem älteren Content-Modell auf das aktuelle migrieren und bei Bedarf Einträge so ändern können, dass sie gemäß dem aktuellen Modell gültig sind. Teams sollten auch Tests schreiben, die ausgeführt werden können, um zu überprüfen, ob die aktuelle Software mit dem aktuellen Content-Modell und dem neuesten Content funktioniert.
Wie soll ich vorgehen
Die Implementierung von CMS als Code erfordert das Speichern des Content-Modells in Ihrem Versionskontroll-Repository zusammen mit dem Rest Ihres Quellcodes, sodass die Version der Software-Revision mit der Version des Content-Modells übereinstimmt. Dies geschieht mithilfe der Migrations-CLI von Contentful, um die Konfiguration aller Contenttypen zu definieren, die der Entwicklungsumgebung hinzugefügt wurden.
Die erste Migration kann automatisch mit dem Befehl „Migration generieren“ erstellt werden. Nachfolgende Migrationen werden von Entwickler*innen erstellt, wenn sich das Content-Modell weiterentwickelt.
Wenn neue Umgebungen erstellt werden, werden sie als Kopie der Produktionsumgebung erstellt.
Datenbanken und Plattformen wie „Ruby on Rails“ verfügen über gut entwickelte Migrationsstrategien. Für „CMS als Code“ müssen die Migrationsskripte vom Team geschrieben werden. Das Migrationstool von Contentful kann bei der Erstellung solcher Skripte helfen.
Traditionelle Migrationen im Rails-Stil haben Up- und Down-Funktionen für jede Version ihrer gespeicherten Content-Modelle. Die Up-Funktion sollte in der Lage sein, eine Space-Umgebung von der vorherigen auf die neueste Version zu migrieren, während die Down-Funktion das Gegenteil tun sollte.
Die Erfahrung aus der Praxis zeigt, dass Teams viele Stunden mit der Wartung von Funktionen verbringen, und dann häufig auf Probleme stoßen, wenn sie versuchen, sie zu nutzen. Oft gibt es keine wirkliche Möglichkeit, Content nach unten zu migrieren, ohne auf Backups zurückzugreifen. Beispielsweise kann alter Content gelöscht worden sein oder Beziehungen, die früher „eins-zu-eins“ waren, können jetzt „eins-zu-viele“ sein, was bedeutet, dass beim Zurücksetzen Content verlieren gehen würde. Ein Forward-Only-Plan ist zusammen mit guten Backups im Allgemeinen eine bessere Option.
Ein Forward-Only-Migrationsplan sollte ein Expand-and-Contract-Muster verwenden, um sicher abwärtskompatible Änderungen an Ihrem Content-Modell vorzunehmen, anstatt Functions zu schreiben.
Die Erweiterungsphase sollte neue Felder und Contenttypen hinzufügen und Content-Einträge so transformieren, dass die Änderungen die Ausführung der aktuell freigegebenen Version der Software nicht verhindern. Indem der vorhandene Content an Ort und Stelle belassen wird, während die Contenttypen und der Content erweitert werden, kann auch die neue Version der Software ausgeführt werden. Das Content-Modell kann nun sowohl die aktuelle Version als auch die neue Version Ihrer Software parallel unterstützen. Ihre Software kann nun für Ihre QA-Nutzer*innen freigegeben und für den Rest Ihrer Nutzerbasis bereitgestellt werden. Wenn zu irgendeinem Zeitpunkt ein Problem auftritt, kann der Rollout gestoppt und rückgängig gemacht werden.
Sobald alle Nutzer*innen Ihre neue Version erfolgreich verwenden, wird die Verkleinerungsphase der Migration ausgeführt, um nicht benötigte Contenttypen, Felder und unnötigen Content zu entfernen.

Um diesen Prozess mit einem einfachen Beispiel zu veranschaulichen, betrachten Sie ein Blog-System, das nur einen Contenttyp hat, nämlich einen Beitrag. Der Contenttyp „Beitrag“ enthält ein Autorenfeld, also ein Textfeld, in das Editor*innen den Namen des Autors/der Autorin eingeben können. In der nächsten Version der Software führen neue Anforderungen dazu, dass das Autorenfeld ein unabhängiger Contenttyp sein muss, auf den vom Beitrag aus verwiesen wird.
Die Erweiterungsphase ändert weder das Autorenfeld noch seinen Content. Vielmehr wird ein neues Feld hinzugefügt, das beispielsweise AuthorRef heißt.
Die Migration würde jeden Beitragseintrag durchlaufen, einen neuen Autoreneintrag für jedes der alten Autorenfelder erstellen und AuthorRef als Verweis auf diesen neuen Autoreneintrag festlegen.
Ihre Redaktionsteams können nun zusätzliche Informationen zu den Autoreneinträgen hinzufügen, während die vorhandene Software weiterhin ausgeführt wird, da sie nur vom alten Autorenfeld abhängt.
Wenn der Content fertig ist, können Sie mit der Einführung Ihrer neuen Software beginnen. Wenn zu irgendeinem Zeitpunkt Probleme auftreten, können Sie den Rollout rückgängig machen.
Sobald der Rollout erfolgreich abgeschlossen wurde, kann Ihre Verkleinerungsphase jetzt ausgeführt und das alte Autorenfeld dauerhaft entfernt werden. Wenn Sie den Namen des alten Feldes anstelle des in der Erweiterungsphase verwendeten Namens verwenden möchten, können Sie dies als eine weitere Migration mit eigenen Erweiterungs- und Verkleinerungsphasen tun. Wenn Sie einfach den neuen Namen verwenden können, ist Ihre Migration abgeschlossen.
Wenn Sie sich in einer Situation befinden, in der Sie wirklich zurückkehren müssen, ist es eine gute Idee, ein Backup zu haben, von dem aus Sie wiederherstellen können. In jedem Fall können Sie eine neue Vorwärtsmigration erstellen, um zum alten Content-Modell zurückzukehren.
Contentful bietet Import-, Export- und Migrationstools mit denen die Bereitstellungs- und Migrationsskripte vereinfacht werden können, sodass agile Teams Ihr CMS als Code behandeln können.