Der Autor hat den Free and Open Source Fund ausgewählt, um eine Spende im Rahmen des Write for DOnations-Programms zu erhalten.
Einführung
Terraform-Module ermöglichen es Ihnen, verschiedene Ressourcen Ihrer Infrastruktur zu einer einzigen, vereinheitlichten Ressource zu gruppieren. Sie können sie später mit möglichen Anpassungen wiederverwenden, ohne die Ressourcendefinitionen jedes Mal wiederholen zu müssen, wenn Sie sie benötigen, was für große und komplex strukturierte Projekte vorteilhaft ist. Sie können Modulinstanzen mit von Ihnen definierten Eingabevariablen anpassen und Informationen aus ihnen extrahieren, indem Sie Ausgaben verwenden. Neben dem Erstellen eigener benutzerdefinierter Module können Sie auch die öffentlich im Terraform-Registrierung veröffentlichten vorgefertigten Module verwenden. Entwickler können sie verwenden und anpassen, indem sie Eingaben wie bei den von Ihnen erstellten Modulen verwenden, aber ihr Quellcode wird in der Cloud gespeichert und von dort abgerufen.
In diesem Tutorial erstellen Sie ein Terraform-Modul, das mehrere Droplets hinter einem Lastenausgleicher für Redundanz einrichtet. Sie werden auch die Schleifenfunktionen for_each
und count
der Hashicorp Configuration Language (HCL) verwenden, um mehrere angepasste Instanzen des Moduls gleichzeitig bereitzustellen.
Voraussetzungen
- A DigitalOcean Personal Access Token, which you can create via the DigitalOcean control panel. You can find instructions in the DigitalOcean product document, How to Create a Personal Access Token.
- Terraform auf Ihrem lokalen Rechner installiert und ein Projekt mit dem DO-Anbieter eingerichtet. Führen Sie Schritt 1 und Schritt 2 des Tutorials So verwenden Sie Terraform mit DigitalOcean aus und stellen Sie sicher, dass Sie den Projektordner
terraform-modules
anstelle vonloadbalance
benennen. Enthalten Sie während Schritt 2 nicht die Variablepvt_key
und die SSH-Schlüssel-Ressource. - Vertrautheit mit HCL-Datentypen und Schleifen. Weitere Informationen finden Sie im Tutorial So verbessern Sie die Flexibilität mit Terraform-Variablen, Abhängigkeiten und Bedingungen.
- Vertrautheit mit Terraform-Ausgaben und ihrer Verwendung. Sie können das Tutorial Wie man Infrastrukturdaten mit Terraform-Ausgaben verwaltet befolgen, um mehr darüber zu erfahren.
Hinweis: Dieses Tutorial wurde speziell mit Terraform 1.1.3
getestet.
Modulstruktur und Vorteile
In diesem Abschnitt erfahren Sie, welche Vorteile Module bringen, wo sie üblicherweise im Projekt platziert sind und wie sie strukturiert sein sollten.
Benutzerdefinierte Terraform-Module werden erstellt, um verbundene Komponenten zu kapseln, die häufig gemeinsam in größeren Projekten verwendet und bereitgestellt werden. Sie sind eigenständig und enthalten nur die Ressourcen, Variablen und Anbieter, die sie benötigen.
Module werden in der Regel in einem zentralen Ordner am Stamm des Projekts gespeichert, jeder in seinem entsprechenden Unterordner darunter. Um eine saubere Trennung zwischen Modulen zu erhalten, sollten sie immer so konzipiert sein, dass sie einen einzigen Zweck haben und sicherstellen, dass sie niemals Untermodule enthalten.
Es ist nützlich, Module aus Ihren Ressourcenschemas zu erstellen, wenn Sie feststellen, dass Sie sie mit seltenen Anpassungen wiederholen. Das Verpacken einer einzelnen Ressource als Modul kann überflüssig sein und entfernt allmählich die Einfachheit der Gesamtarchitektur.
Für kleine Entwicklungs- und Testprojekte ist die Integration von Modulen nicht erforderlich, da sie in diesen Fällen keine wesentliche Verbesserung bringen. Mit ihrer Anpassungsfähigkeit sind Module das Baumaterial komplex strukturierter Projekte. Entwickler verwenden Module für größere Projekte aufgrund der erheblichen Vorteile bei der Vermeidung von Code-Duplizierung. Module bieten auch den Vorteil, dass Definitionen nur an einer Stelle geändert werden müssen, was dann durch den Rest der Infrastruktur propagiert wird.
Als nächstes definieren, verwenden und passen Sie Module in Ihren Terraform-Projekten an.
Erstellen eines Moduls
In diesem Abschnitt definieren Sie mehrere Droplets und einen Lastenausgleicher als Terraform-Ressourcen und packen sie in ein Modul. Sie werden auch das resultierende Modul anpassbar machen, indem Sie Modul-Eingaben verwenden.
Sie werden das Modul in einem Verzeichnis mit dem Namen droplet-lb
unter einem Verzeichnis namens modules
speichern. Angenommen, Sie befinden sich im Verzeichnis terraform-modules
, das Sie als Teil der Voraussetzungen erstellt haben, erstellen Sie beide auf einmal, indem Sie Folgendes ausführen:
Das -p
-Argument weist mkdir
an, alle Verzeichnisse im angegebenen Pfad zu erstellen.
Wechseln Sie dazu:
Wie bereits im vorherigen Abschnitt erwähnt wurde, enthalten Module die Ressourcen und Variablen, die sie verwenden. Ab Terraform 0.13
müssen sie auch Definitionen der von ihnen verwendeten Provider enthalten. Module erfordern keine spezielle Konfiguration, um anzugeben, dass der Code ein Modul darstellt, da Terraform jedes Verzeichnis, das HCL-Code enthält, als Modul betrachtet, auch das Stammverzeichnis des Projekts.
In einem Modul definierte Variablen werden als dessen Eingaben freigegeben und können in Ressourcendefinitionen verwendet werden, um sie anzupassen. Das von Ihnen erstellte Modul wird zwei Eingaben haben: die Anzahl der zu erstellenden Droplets und den Namen ihrer Gruppe. Erstellen Sie eine Datei mit dem Namen variables.tf
und öffnen Sie sie zur Bearbeitung, in der Sie die Variablen speichern werden:
Fügen Sie die folgenden Zeilen hinzu:
Speichern und schließen Sie die Datei.
Sie speichern die Droplet-Definition in einer Datei namens droplets.tf
. Erstellen Sie diese Datei und öffnen Sie sie zum Bearbeiten:
Fügen Sie die folgenden Zeilen hinzu:
Für den Parameter count
, der angibt, wie viele Instanzen einer Ressource erstellt werden sollen, übergeben Sie die Variable droplet_count
. Ihr Wert wird festgelegt, wenn das Modul aus dem Hauptprojektcode aufgerufen wird. Der Name jedes bereitgestellten Droplets wird unterschiedlich sein, was Sie durch Anhängen des Index des aktuellen Droplets an den angegebenen Gruppennamen erreichen. Die Bereitstellung der Droplets erfolgt in der Region fra1
, und sie werden Ubuntu 20.04 ausführen.
Wenn Sie fertig sind, speichern und schließen Sie die Datei.
Mit den nun definierten Droplets können Sie mit der Erstellung des Lastenausgleichs fortfahren. Sie speichern seine Ressourcendefinition in einer Datei namens lb.tf
. Erstellen und öffnen Sie sie zum Bearbeiten, indem Sie Folgendes ausführen:
Fügen Sie die Ressourcendefinition hinzu:
Sie definieren den Lastenausgleicher mit dem Gruppennamen in seinem Namen, um ihn unterscheidbar zu machen. Sie setzen ihn zusammen mit den Droplets in der Region fra1
bereit. Die nächsten beiden Abschnitte geben die Ziel- und Überwachungsports sowie Protokolle an.
Der markierte droplet_ids
-Block nimmt die IDs der Droplets entgegen, die vom Lastenausgleicher verwaltet werden sollen. Da es mehrere Droplets gibt und ihre Anzahl im Voraus nicht bekannt ist, verwenden Sie eine for
-Schleife, um die Sammlung von Droplets (digitalocean_droplet.droplets
) zu durchlaufen und ihre IDs zu nehmen. Sie umgeben die for
-Schleife mit Klammern ([]
), damit die resultierende Sammlung eine Liste ist.
Speichern Sie die Datei und schließen Sie sie.
Sie haben jetzt das Droplet, den Lastenausgleicher und die Variablen für Ihr Modul definiert. Sie müssen die Anforderungen des Anbieters definieren und angeben, welche Anbieter das Modul verwendet, einschließlich ihrer Version und wo sie sich befinden. Seit Terraform 0.13
müssen Module die Quellen von nicht von Hashicorp gewarteten Anbietern, die sie verwenden, explizit definieren. Dies liegt daran, dass sie sie nicht vom übergeordneten Projekt erben.
Die Anforderungen des Anbieters speichern Sie in einer Datei mit dem Namen provider.tf
. Erstellen Sie sie zum Bearbeiten, indem Sie Folgendes ausführen:
Fügen Sie die folgenden Zeilen hinzu, um den digitalocean
-Anbieter zu benötigen:
Speichern und schließen Sie die Datei, wenn Sie fertig sind. Das droplet-lb
-Modul erfordert jetzt den digitalocean
-Anbieter.
Module unterstützen auch Ausgaben, die Sie verwenden können, um interne Informationen über den Zustand ihrer Ressourcen abzurufen. Sie werden eine Ausgabe definieren, die die IP-Adresse des Lastenausgleichers freigibt, und sie in einer Datei mit dem Namen outputs.tf
speichern. Erstellen Sie sie zum Bearbeiten:
Fügen Sie die folgende Definition hinzu:
Diese Ausgabe ruft die IP-Adresse des Lastenausgleichers ab. Speichern und schließen Sie die Datei.
Das Modul droplet-lb
ist nun funktional vollständig und bereit für den Einsatz. Sie werden es aus dem Hauptcode aufrufen, den Sie im Stammverzeichnis des Projekts speichern werden. Navigieren Sie zunächst dorthin, indem Sie zweimal durch Ihr Dateiverzeichnis nach oben gehen:
Dann erstellen und öffnen Sie eine Datei namens main.tf
zur Bearbeitung, in der Sie das Modul verwenden werden:
Fügen Sie die folgenden Zeilen hinzu:
In dieser Deklaration rufen Sie das Modul droplet-lb
auf, das sich im angegebenen Verzeichnis source
befindet. Sie konfigurieren die Eingabe, die es bereitstellt, droplet_count
und group_name
, die auf group1
gesetzt sind, damit Sie später zwischen Instanzen unterscheiden können.
Da die Ausgabe der Load-Balancer-IP in einem Modul definiert ist, wird sie nicht automatisch angezeigt, wenn Sie das Projekt anwenden. Die Lösung dafür besteht darin, eine weitere Ausgabe zu erstellen, um ihren Wert abzurufen (loadbalancer_ip
).
Speichern Sie die Datei und schließen Sie sie, wenn Sie fertig sind.
Initialisieren Sie das Modul, indem Sie Folgendes ausführen:
Die Ausgabe wird so aussehen:
OutputInitializing modules...
- groups in modules/droplet-lb
Initializing the backend...
Initializing provider plugins...
- Finding digitalocean/digitalocean versions matching "~> 2.0"...
- Installing digitalocean/digitalocean v2.19.0...
- Installed digitalocean/digitalocean v2.19.0 (signed by a HashiCorp partner, key ID F82037E524B9C0E8)
...
Terraform has been successfully initialized!
You may now begin working with Terraform. Try running "terraform plan" to see
any changes that are required for your infrastructure. All Terraform commands
should now work.
If you ever set or change modules or backend configuration for Terraform,
rerun this command to reinitialize your working directory. If you forget, other
commands will detect it and remind you to do so if necessary.
Sie können versuchen, das Projekt zu planen, um zu sehen, welche Aktionen Terraform durchführen würde, indem Sie Folgendes ausführen:
Die Ausgabe wird ähnlich wie folgt sein:
Dieser Output zeigt, dass Terraform drei Droplets erstellen würde, die group1-0
, group1-1
und group1-2
heißen, und auch einen Load Balancer namens group1-lb
erstellen würde, der den Datenverkehr zu und von den drei Droplets verwaltet.
Sie können versuchen, das Projekt auf die Cloud anzuwenden, indem Sie folgendes ausführen:
Geben Sie yes
ein, wenn Sie dazu aufgefordert werden. Der Output wird alle Aktionen zeigen, und die IP-Adresse des Load Balancers wird ebenfalls angezeigt:
Sie haben ein Modul erstellt, das eine anpassbare Anzahl von Droplets und einen Load Balancer enthält, der automatisch konfiguriert wird, um ihren ein- und ausgehenden Datenverkehr zu verwalten.
Umbenennung bereitgestellter Ressourcen
Im vorherigen Abschnitt haben Sie das von Ihnen definierte Modul bereitgestellt und es groups
genannt. Wenn Sie jemals den Namen ändern möchten, führt das einfache Umbenennen des Modulaufrufs nicht zu den erwarteten Ergebnissen. Das Umbenennen des Aufrufs veranlasst Terraform, Ressourcen zu zerstören und neu zu erstellen, was zu übermäßiger Ausfallzeit führt.
Zum Beispiel öffnen Sie main.tf
zur Bearbeitung, indem Sie Folgendes ausführen:
Benennen Sie das Modul groups
in groups_renamed
um, wie hier hervorgehoben:
Speichern und schließen Sie die Datei. Initialisieren Sie dann das Projekt erneut:
Sie können jetzt das Projekt planen:
Die Ausgabe wird lang sein, aber ähnlich aussehen wie diese:
Output...
Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
+ create
- destroy
Terraform will perform the following actions:
# module.groups.digitalocean_droplet.droplets[0] wird zerstört
...
# module.groups_renamed.digitalocean_droplet.droplets[0] wird erstellt
...
Terraform wird Sie auffordern, die vorhandenen Instanzen zu zerstören und neue zu erstellen. Dies ist zerstörerisch und unnötig und kann zu unerwünschter Ausfallzeit führen.
Verwenden Sie stattdessen den moved
-Block, um Terraform anzuweisen, alte Ressourcen unter dem neuen Namen zu verschieben. Öffnen Sie main.tf
zur Bearbeitung und fügen Sie am Ende der Datei die folgenden Zeilen hinzu:
Wenn Sie fertig sind, speichern und schließen Sie die Datei.
Sie können jetzt das Projekt planen:
Wenn Sie mit dem moved
-Block in main.tf
planen, möchte Terraform die Ressourcen verschieben, anstatt sie neu zu erstellen:
OutputTerraform will perform the following actions:
# Das Modul module.groups.digitalocean_droplet.droplets[0] wurde nach module.groups_renamed.digitalocean_droplet.droplets[0] verschoben
...
# Das Modul module.groups.digitalocean_droplet.droplets[1] wurde nach module.groups_renamed.digitalocean_droplet.droplets[1] verschoben
...
Das Verschieben von Ressourcen ändert ihre Position im Terraform-Zustand, was bedeutet, dass die tatsächlichen Cloud-Ressourcen nicht geändert, zerstört oder neu erstellt werden.
Aufgrund der erheblichen Änderungen an der Konfiguration im nächsten Schritt sollten die bereitgestellten Ressourcen zerstört werden, indem Sie Folgendes ausführen:
Geben Sie yes
ein, wenn Sie dazu aufgefordert werden. Die Ausgabe endet mit:
Output...
Destroy complete! Resources: 4 destroyed.
In diesem Abschnitt haben Sie Ressourcen in Ihrem Terraform-Projekt umbenannt, ohne sie dabei zu zerstören. Jetzt werden Sie mehrere Instanzen eines Moduls aus demselben Code mithilfe von for_each
und count
bereitstellen.
Bereitstellen mehrerer Modulinstanzen
In diesem Abschnitt verwenden Sie count
und for_each
, um das Modul droplet-lb
mehrmals mit Anpassungen bereitzustellen.
Verwenden von count
Ein Weg, um mehrere Instanzen des gleichen Moduls gleichzeitig bereitzustellen, besteht darin, die Anzahl über den Parameter count
zu übergeben, der automatisch für jedes Modul verfügbar ist. Öffnen Sie main.tf
zur Bearbeitung:
Ändern Sie es so, dass es wie folgt aussieht, entfernen Sie die vorhandene Output-Definition und den moved
-Block:
Indem Sie count
auf 3
setzen, weisen Sie Terraform an, das Modul dreimal bereitzustellen, jedes Mal mit einem anderen Gruppennamen. Wenn Sie fertig sind, speichern und schließen Sie die Datei.
Planen Sie die Bereitstellung, indem Sie Folgendes ausführen:
Die Ausgabe wird lang sein und so aussehen:
Die Ausgabe enthält Details dazu, dass jede der drei Modulinstanten drei Droplets und einen Lastenausgleicher mit ihnen verbunden hätte.
Mit for_each
verwenden
Sie können for_each
für Module verwenden, wenn Sie eine komplexere Instanzenanpassung benötigen oder wenn die Anzahl der Instanzen von Drittanbieterdaten abhängt (oft als Maps präsentiert), die beim Schreiben des Codes nicht bekannt sind.
Definieren Sie nun eine Map, die Gruppennamen mit Droplet-Zählungen verbindet und Instanzen von droplet-lb
entsprechend bereitstellt. Öffnen Sie zum Bearbeiten main.tf
, indem Sie folgenden Befehl ausführen:
Ändern Sie die Datei so, dass sie wie folgt aussieht:
Sie definieren zunächst eine Map namens group_counts
, die angibt, wie viele Droplets eine bestimmte Gruppe haben soll. Anschließend rufen Sie das Modul droplet-lb
auf, geben jedoch an, dass die for_each
-Schleife auf var.group_counts
ausgeführt werden soll, die Map, die Sie gerade zuvor definiert haben. droplet_count
nimmt each.value
an, den Wert des aktuellen Paares, der die Anzahl der Droplets für die aktuelle Gruppe ist. group_name
erhält den Namen der Gruppe.
Speichern und schließen Sie die Datei, wenn Sie fertig sind.
Versuchen Sie, die Konfiguration anzuwenden, indem Sie folgenden Befehl ausführen:
Die Ausgabe wird die Aktionen detaillieren, die Terraform unternehmen würde, um die beiden Gruppen mit ihren Droplets und Lastenausgleichern zu erstellen:
In diesem Schritt haben Sie count
und for_each
verwendet, um mehrere benutzerdefinierte Instanzen desselben Moduls aus demselben Code zu erstellen.
Abschluss
In diesem Tutorial haben Sie Terraform-Module erstellt und bereitgestellt. Sie haben Module verwendet, um logisch verknüpfte Ressourcen zu gruppieren und sie angepasst, um mehrere verschiedene Instanzen aus einer zentralen Code-Definition bereitzustellen. Außerdem haben Sie Ausgaben verwendet, um Attribute von Ressourcen anzuzeigen, die im Modul enthalten sind.
Wenn Sie mehr über Terraform erfahren möchten, schauen Sie sich unsere Serie Wie man Infrastruktur mit Terraform verwaltet an.
Source:
https://www.digitalocean.com/community/tutorials/how-to-build-a-custom-terraform-module