Mitverfasst von dem großartigen Daniel Lamando
Einführung
Die Verwendung von Modulen, um Ihren Terraform-Code DRY („Don’t Repeat Yourself“) zu halten, ist sehr verbreitet, aber die beste Methode zur Veröffentlichung und Verteilung dieser Module zu finden, ist nicht immer einfach. Auch wir bei Forto sind schnell auf diese Herausforderung gestoßen, als immer mehr Teams in unserer Organisation begannen, Terraform zu nutzen, um ihre Infrastruktur mit Code zu beschreiben. Aufmerksame Leser unseres vorherigen Terraform-Blogposts könnten sogar ein kleines Easter Egg bemerkt haben:
Dieses Snippet zeigt, wie wir Terraform-Module damals referenzierten, und offenbarte eine bedeutende technische Schuld: die Referenzierung von unversionierten Terraform-Modulen per Pfad. Diese Praxis machte jede Änderung an einem Modul zu einem riskanten Unterfangen. In einigen Fällen erstellten wir zusätzliche Kopien unserer Module, um das Risiko zu minimieren (was zu „@v2“ führte, wie im Screenshot zu sehen).
Als wir erkannten, dass wir unsere Terraform-Module versionieren mussten, plante ich einen Hack Day, um eine Lösung zu finden. Zum Kontext: Forto veranstaltet monatlich eintägige Hackathons, bei denen Ingenieure ermutigt werden, an individuellen Projekten zu arbeiten, die nichts mit ihrer täglichen Arbeit zu tun haben. Diese Projekte können von Machine Learning bis hin zur Musik-Synthese reichen. Dennoch nutzen wir diese Hackathons manchmal, um Prototypen oder Lösungen zu entwickeln, die zwar mit unserer Arbeit zusammenhängen, aber nicht sofort priorisiert werden.
Das Versionierungstool unserer Wahl für diesen ersten Hack Day war Versio. Während unsere Versio-Implementierung funktionierte, um Versionsnummern zu erhöhen und Releases unserer Module zu erstellen, stießen wir auf einige kleinere Probleme. Als dann immer mehr Ingenieure in der Firma Moduländerungen vornahmen, wurden die Nachteile der zusätzlichen Komplexität deutlich. Nach ein paar Monaten entschieden wir uns, einen zweiten Hack Day zu organisieren, um zu prüfen, ob eine einfachere Lösung von Grund auf effektiver sein könnte.
Unser neuer Workflow erlaubt es weiterhin, Terraform-Module innerhalb eines Monorepos individuell zu versionieren. Der Release-Prozess ist jetzt jedoch eng mit dem Pull-Request-Lebenszyklus verknüpft. Nach der Zusammenführung eines Pull Requests wird eine neue Versionsnummer berechnet, und die erstellten Artefakte werden in einem S3-Bucket abgelegt. Abschließend wird das Wiki des Repositories mit automatisch generierter Moduldokumentation und einem neuen Changelog-Eintrag aktualisiert. Das Ergebnis ist ein vereinfachter Versionierungs-Workflow, der verschiedene GitHub-Funktionen wie PR-Labels, GitHub Actions und die GraphQL-API nutzt.
In den folgenden Abschnitten erklären wir, warum wir unsere Module versionieren, teilen die Entscheidungen, die wir getroffen haben, und zeigen einen beispielhaften Ablauf eines Modul-Upgrades.
Wir haben außerdem ein öffentliches Referenz-Repository erstellt: github.com/freight-hub/terraform-modules-demo, damit jeder diesen Workflow einfach in seinen eigenen Repositories umsetzen kann.
(„Freighthub“ war Fortos vorheriger Markenname. Ehrlich gesagt, steht die Umbenennung unserer GitHub-Organisation ganz oben auf dem Jira-Board!)
Der Ablauf
Änderung an einem Modul vornehmen
Das gehört schließlich zu Ihrem Job.
Das neue Modul vor der Veröffentlichung testen
Wenn Sie Ihren Code lokal testen möchten, können Sie eine quellpfadbasierte Modulreferenz im Dateisystem verwenden, wie zum Beispiel:
Falls Sie die unveröffentlichte Änderung von der CI/CD-Pipeline testen lassen möchten (siehe vorherigen Artikel), können Sie eine git-basierte Modulreferenz verwenden, wie zum Beispiel:
Öffnen Sie einen Pull Request (PR) für die Änderung.
Stellen Sie sicher, dass Sie den für das Changelog vorgesehenen Text in die PR-Beschreibung einfügen. Ein aussagekräftiger Changelog-Text sorgt dafür, dass die Versionshistorie genau und nützlich bleibt.
Verwenden Sie das Modul über die S3-URL
Private Repositories sollten S3-URLs nutzen, damit Terraform die AWS-Authentifizierung und -Autorisierung verwenden kann. Öffentliche Repositories können einfach normale HTTP-URLs nutzen.
source = “s3:https://forto-terrform-modules-demo.s3.eu-west-1.amazonaws.com/terraform-aws-vpc-1.1.0.zip”
Die Überlegung
Warum sollten Module überhaupt versioniert werden
Deterministisches Verhalten – Überraschungen sind vielleicht nett bei Geburtstagen, aber nicht in Code-Repositories für Infrastruktur! Operatoren sollten Änderungen an ihren Infrastruktur-Objekten nur erwarten, wenn sie den Code in ihrem Terraform-Arbeitsbereich ändern, unabhängig davon, was an den Modulen gemacht wurde. Wenn eine neue Version eines Moduls benötigt wird (z. B. zur Behebung eines Fehlers oder zum Hinzufügen von Funktionen), muss eine explizite Änderung am Terraform-Arbeitsbereich vorgenommen werden. Dadurch wird sichergestellt, dass Richtlinien wie GitHub CODEOWNER Required Reviews eingehalten werden.
Warum SemVer?
Die Nutzer der Module können leicht erkennen, ob sie vor einem Upgrade einen Blick in das Changelog werfen müssen, da Hauptversionen auf große oder breaking Changes hinweisen. Dabei ist zu beachten, dass Patch-Versionen nicht unbedingt weniger Risiko mit sich bringen als Minor- oder sogar Major-Versionen. Das Risiko wird durch Tests sowie Code- und Plan-Reviews gemanagt.
Unsere nächsten Schritte
Der große Nachteil einer strikten Versionierung ist der sogenannte Versionsdrift. Upgrades müssen explizit durchgeführt werden, und wenn diese nicht konsequent umgesetzt werden, bleiben frühere Versionen der Module in Gebrauch, lange nachdem neue Versionen verfügbar sind.
Wir planen, einen weiteren Job in die Terraform-Module-Pipeline zu integrieren, der automatisch PRs (Pull Requests) öffnet, um alle Modulreferenzen im Workspaces-Root-Repository auf die neueste Version zu aktualisieren.
Für Minor- und Patch-Versionserhöhungen sollten diese PRs direkt bereit sein, um wie vorgegeben gemergt zu werden. Major-Versionserhöhungen hingegen würden als Entwurfs-PRs geöffnet, da wir davon ausgehen, dass größere oder breaking Changes mehr Arbeit erfordern, bevor die PRs für den Merge bereit sind.