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:
![This image shows a code snippet within a Terraform configuration file, specifically focusing on an AWS SQS (Simple Queue Service) module. The file being edited is named sqs.tf, and the code snippet uses a module named sqs_example_queue. Key parameters are defined within the module, including source, queue_name, and dead_letter_queue_create.
A notable part of the image is a highlighted warning: "../../../../modules/aws-sqs-queue@v2" # don't version your modules like this. This comment suggests that specifying module versions directly within the file path (such as @v2 in the directory structure) is considered a bad practice in Terraform. Proper module versioning should ideally be managed through Terraform’s versioning mechanisms rather than hardcoding the version within file paths.
Below the code snippet, additional context shows that this code change is part of a pull request titled "DLQ FTW!!![production]" with a reviewer assigned and relevant labels for promotion and automation.
This image highlights the importance of following best practices in Terraform module management to ensure code maintainability and avoid issues associated with improper versioning methods.](https://forto.com/wp-content/uploads/resized/2024/11/0_dDoeurxtNu8QYqA--768x0-c-default.png)
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.



![This image shows a terminal output from an automated GitHub Action that pushes recent changes to a GitHub repository’s wiki. The update here documents a new release version for a Terraform module, specifically updating the terraform-aws-vpc module to version 1.1.0.
Key details in the output include:
Git Configuration: The command Run git config --local user.email "github-actions[bot]@users.noreply.github.com" configures the GitHub bot's email for this commit, indicating that this change was automated through GitHub Actions rather than manually pushed by a user.
Version Update: The line [master cecacc5] terraform-aws-vpc @ 1.1.0 specifies the module and the new version number, 1.1.0, reflecting the minor update made to the module.
File Change Summary: The output shows that one file was changed, with 11 insertions and 4 deletions, suggesting modifications to the documentation or versioning file in the wiki.
Push to Wiki Repository: The update is pushed to the URL https://github.com/freight-hub/terraform-modules-demo.wiki, which points to the wiki section of the terraform-modules-demo repository, indicating that documentation or release notes are being updated to reflect the latest changes.
This automated update ensures that documentation in the GitHub Wiki is synchronized with the latest release, allowing users to access up-to-date information on module versions and changes. This process maintains consistency in version tracking and enhances transparency in the module’s development lifecycle by making sure that each release is well-documented and accessible directly from the wiki.](https://forto.com/wp-content/uploads/resized/2024/11/0_dLoWOyjJq1psRvSi-768x0-c-default.png)



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.