Erstellen eines benutzerdefinierten Terraform-Moduls

0 Aktien
0
0
0
0

Einführung

Terraform-Module ermöglichen es Ihnen, die verschiedenen Ressourcen Ihrer Infrastruktur zu einer einzigen, einheitlichen Ressource zusammenzufassen. Diese können Sie später mit möglichen Anpassungen wiederverwenden, ohne die Ressourcendefinitionen jedes Mal wiederholen zu müssen. Dies ist besonders nützlich für große Projekte mit komplexen Strukturen. Sie können Modulinstanzen mithilfe von selbst definierten Eingabevariablen anpassen und Informationen über deren Ausgaben extrahieren. Neben der Erstellung eigener Module können Sie auch vorgefertigte Module verwenden, die öffentlich in der Terraform-Registry veröffentlicht sind. Entwickler können diese Module mit denselben Eingaben wie Ihre eigenen Module verwenden und anpassen, der Quellcode wird jedoch innerhalb und außerhalb der Cloud gespeichert. In diesem Tutorial erstellen Sie ein Terraform-Modul, das mehrere Droplets hinter einem Load Balancer für Redundanz startet. Sie verwenden außerdem die Schleifenfunktionen `for_each` und `count` der HashiCorp Configuration Language (HCL), um mehrere angepasste Modulinstanzen gleichzeitig bereitzustellen.

Voraussetzungen
  • Ein persönlicher DigitalOcean-Zugangscode
  • Terraform ist auf Ihrem System installiert und ein Projekt wurde mit dem DO-Provider eingerichtet.
  • Einführung in Datentypen und HCL-Schleifen
  • Einführung in Terraform-Ausgaben und deren Verwendung

Modulstruktur und Vorteile

In diesem Abschnitt erfahren Sie mehr über die Vorteile von Modulen, wo sie typischerweise in einem Projekt platziert werden und wie sie strukturiert sein sollten. Benutzerdefinierte Terraform-Module dienen der Kapselung verbundener Komponenten, die häufig in größeren Projekten verwendet und gemeinsam bereitgestellt werden. Sie sind in sich abgeschlossen und enthalten nur die benötigten Ressourcen, Variablen und Provider. Module werden üblicherweise in einem zentralen Ordner im Projektstammverzeichnis gespeichert, jedes in einem eigenen Unterordner. Um eine klare Trennung zwischen Modulen zu gewährleisten, sollten diese immer nur einen einzigen Zweck erfüllen und keine Submodule enthalten. Die Zusammenfassung einer einzelnen Ressource als Modul kann redundant sein und die Einfachheit der Gesamtarchitektur beeinträchtigen. Für kleine Entwicklungs- und Testprojekte ist die Kombination von Modulen nicht notwendig, da sie in diesen Fällen keinen großen Nutzen bringt. Module bieten außerdem den Vorteil, dass Definitionen nur an einer Stelle geändert werden müssen, die Änderungen werden dann automatisch an die gesamte Infrastruktur weitergegeben.

Anschließend definieren, verwenden und passen Sie Module in Ihren Terraform-Projekten an.

Modul erstellen

In diesem Abschnitt definieren Sie mehrere Droplets und einen Load Balancer als Terraform-Ressourcen und fassen diese in einem Modul zusammen. Anschließend konfigurieren Sie das resultierende Modul mithilfe konfigurierbarer Moduleingaben.

Platzieren Sie das Modul in einem Verzeichnis namens Tropfen-PfundSie speichern die Dateien in einem Verzeichnis namens „modules“. Angenommen, Sie befinden sich im Verzeichnis „terraform-modules“, das Sie im Rahmen der Voraussetzungen erstellt haben, installieren Sie beide gleichzeitig mit folgendem Befehl:

mkdir -p modules/droplet-lb

Das Argument -p weist mkdir an, alle Verzeichnisse im angegebenen Pfad zu erstellen.

Geh dorthin:

cd modules/droplet-lb

Wie im vorherigen Abschnitt erwähnt, enthalten Module die von ihnen verwendeten Ressourcen und Variablen. Ab Terraform 0.13 müssen sie zusätzlich Definitionen der verwendeten Provider enthalten. Module benötigen keine spezielle Konfiguration, um anzugeben, dass der Code ein Modul darstellt, da Terraform jedes Verzeichnis mit HCL-Code als Modul betrachtet, selbst das Projektstammverzeichnis.

In einem Modul definierte Variablen werden als dessen Eingaben bereitgestellt und können in Ressourcendefinitionen zur Anpassung verwendet werden. Das von Ihnen erstellte Modul hat zwei Eingaben: die Anzahl der zu erstellenden Droplets und den Namen ihrer Gruppe. Um eine Datei namens „Droplets“ zu bearbeiten, gehen Sie wie folgt vor: variables.tf Erstellen und öffnen Sie den Speicherort für die Variablen:

nano variables.tf

Fügen Sie die folgenden Zeilen hinzu:

variable "droplet_count" {}
variable "group_name" {}

Datei speichern und schließen.

Sie definieren das Droplet in einer Datei namens droplets.tf Sie werden es speichern. Erstellen und öffnen Sie es zur Bearbeitung:

nano droplets.tf

Fügen Sie die folgenden Zeilen hinzu:

resource "digitalocean_droplet" "droplets" {
count = var.droplet_count
image = "ubuntu-22-04-x64"
name = "${var.group_name}-${count.index}"
region = "fra1"
size = "s-1vcpu-1gb"
lifecycle {
precondition {
condition = var.droplet_count >= 2
error_message = "At least two droplets must be created."
}
}
}

Für Parameter zählenSie übergeben die Variable `droplet_count`, die angibt, wie viele Instanzen einer Ressource erstellt werden sollen. Ihr Wert wird beim Aufruf des Moduls aus dem Hauptprojektcode ermittelt. Jeder bereitgestellte Droplet erhält einen anderen Namen. Dies wird erreicht, indem der Index des aktuellen Droplets an den angegebenen Gruppennamen angehängt wird. Bereitstellung von Droplets in der Zone fra1 Es wird Ubuntu 22.04 sein und darauf laufen.

Abschnitt Lebenszyklus Enthält ein Voraussetzung Diese Validierung wird ausgeführt, bevor die Ressourcen tatsächlich bereitgestellt werden. Dabei wird überprüft, ob mindestens zwei Drops erstellt werden – nur ein Drop würde den Zweck des Load Balancers zunichtemachen. Ein weiteres Beispiel für Validierungen findet sich im k8s-bootstrapper-Repository, das Vorlagen für die Einrichtung eines DigitalOcean-Kubernetes-Clusters mit Terraform enthält. Dort dienen die Validierungen dazu, sicherzustellen, dass die Anzahl der Knoten im Cluster im zulässigen Bereich liegt.

Wenn Sie fertig sind, speichern und schließen Sie die Datei.

Nachdem die Droplets definiert wurden, können Sie mit der Erstellung des Load Balancers fortfahren. Definieren Sie dessen Quellcode in einer Datei namens lb.tf Sie werden die Datei speichern. Erstellen und öffnen Sie sie zur Bearbeitung, indem Sie Folgendes ausführen:

nano lb.tf

Fügen Sie die zugehörige Quelldefinition hinzu:

resource "digitalocean_loadbalancer" "www-lb" {
name = "lb-${var.group_name}"
region = "fra1"
forwarding_rule {
entry_port = 80
entry_protocol = "http"
target_port = 80
target_protocol = "http"
}
healthcheck {
port = 22
protocol = "tcp"
}
droplet_ids = [
for droplet in digitalocean_droplet.droplets:
droplet.id
]
}

Sie definieren den Load Balancer, indem Sie den Gruppennamen in seinen Namen aufnehmen, damit er erkennbar ist. Sie definieren ihn zusammen mit den Paketverlusten in der Zone. fra1 In den nächsten beiden Abschnitten werden die Ziel- und Überwachungsports sowie die Protokolle spezifiziert.

Der hervorgehobene Block `droplet_ids` ruft die IDs der Droplets ab, die vom Load Balancer verwaltet werden müssen. Da mehrere Droplets vorhanden sind und deren Anzahl nicht im Voraus bekannt ist, wird eine for-Schleife verwendet, um die Droplet-Liste (digitalocean_droplet.droplets) zu durchlaufen und deren IDs zu ermitteln. Die for-Schleife wird in eckige Klammern ([]) eingeschlossen, sodass die resultierende Liste eine Liste ist.

Datei speichern und schließen.

Nachdem Sie Droplet, Load Balancer und Variablen für Ihr Modul definiert haben, müssen Sie die Provider-Anforderungen festlegen und angeben, welche Provider das Modul verwenden soll, einschließlich ihrer Version und ihres Speicherorts. Ab Terraform 0.13 müssen Module die Nicht-HashiCorp-Provider-Ressourcen, die sie verwenden, explizit definieren. Dies ist erforderlich, da sie diese nicht vom übergeordneten Projekt erben.

Die Anforderungen an den Anbieter definieren Sie in einer Datei namens provider.tf Sie werden die Datei speichern. Um sie bearbeiten zu können, führen Sie folgenden Befehl aus:

nano provider.tf

Fügen Sie die folgenden Zeilen hinzu, um den Digitalocean-Anbieter einzubinden:

terraform {
required_providers {
digitalocean = {
source = "digitalocean/digitalocean"
version = "~> 2.0"
}
}
}

Nach Fertigstellung die Datei speichern und schließen. Modul Tropfen-Pfund Nun zum Anbieter Digitalocean Bedürfnisse.

Module unterstützen außerdem Ausgaben, mit denen Sie interne Informationen über den Status ihrer Ressourcen extrahieren können. Sie definieren eine Ausgabe, die die IP-Adresse des Load Balancers anzeigt, und speichern diese in einer Datei namens outputs.tf Speichern. Zur Bearbeitung erstellen:

nano outputs.tf

Fügen Sie die folgende Definition hinzu:

output "lb_ip" {
value = digitalocean_loadbalancer.www-lb.ip
}

Diese Ausgabe ruft die IP-Adresse des Load Balancers ab. Speichern und schließen Sie die Datei.

Modul Tropfen-Pfund Es ist nun voll funktionsfähig und bereit für den Einsatz. Sie rufen es aus dem Hauptcode auf, den Sie im Stammverzeichnis des Projekts speichern. Navigieren Sie zunächst dorthin, indem Sie im Dateiverzeichnis oben doppelklicken:

cd ../..

Dann eine Datei namens main.tf Erstellen und zur Bearbeitung öffnen Sie den Bereich, in dem Sie das Modul verwenden werden:

nano main.tf

Fügen Sie die folgenden Zeilen hinzu:

module "groups" {
source = "./modules/droplet-lb"
droplet_count = 3
group_name = "group1"
}
output "loadbalancer-ip" {
value = module.groups.lb_ip
}

In dieser Ankündigung wird das Modul vorgestellt. Tropfen-Pfund Sie rufen das Quellverzeichnis auf, das sich im angegebenen Verzeichnis befindet. Die von ihm bereitgestellte Eingabe ist Anzahl der Tropfen Und Gruppenname Sie konfigurieren es so, dass es auf Gruppe 1 eingestellt ist, damit Sie später zwischen den Instanzen unterscheiden können.

Da die Load-Balancer-IP-Adresse in einem Modul definiert ist, wird sie beim Deployment des Projekts nicht automatisch angezeigt. Die Lösung besteht darin, eine weitere Ausgabe zu erstellen, indem ihr Wert (loadbalancer_ip) abgerufen wird.

Wenn Sie fertig sind, speichern und schließen Sie die Datei.

Starten Sie das Modul mit folgendem Befehl:

terraform init

Die Ausgabe wird wie folgt 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.34.1...
- Installed digitalocean/digitalocean v2.34.1 (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 das Projekt planen, um zu sehen, welche Aktionen Terraform bei der Ausführung durchführen wird:

terraform plan -var "do_token=${DO_PAT}"

Die Ausgabe wird in etwa so aussehen:

Output...
Terraform used the selected providers to generate the following execution plan. Resource actions are
indicated with the following symbols:
+ create
Terraform will perform the following actions:
# module.groups.digitalocean_droplet.droplets[0] will be created
+ resource "digitalocean_droplet" "droplets" {
...
+ name = "group1-0"
...
}
# module.groups.digitalocean_droplet.droplets[1] will be created
+ resource "digitalocean_droplet" "droplets" {
...
+ name = "group1-1"
...
}
# module.groups.digitalocean_droplet.droplets[2] will be created
+ resource "digitalocean_droplet" "droplets" {
...
+ name = "group1-2"
...
}
# module.groups.digitalocean_loadbalancer.www-lb will be created
+ resource "digitalocean_loadbalancer" "www-lb" {
...
+ name = "lb-group1"
...
}
Plan: 4 to add, 0 to change, 0 to destroy.
...

Diese Ausgabe erklärt, dass Terraform drei Droplets mit den Namen group1-0, group1-1 und group1-2 erstellt und außerdem einen Load Balancer mit dem Namen group1-lb erstellt, der den Datenverkehr zu und von den drei Droplets verarbeitet.

Sie können das Projekt in der Cloud bereitstellen, indem Sie Folgendes ausführen:

terraform apply -var "do_token=${DO_PAT}"

Geben Sie bei Aufforderung „Ja“ ein. Die Ausgabe zeigt alle Aktionen an, und die IP-Adresse des Load Balancers wird ebenfalls angezeigt:

Outputmodule.groups.digitalocean_droplet.droplets[1]: Creating...
module.groups.digitalocean_droplet.droplets[0]: Creating...
module.groups.digitalocean_droplet.droplets[2]: Creating...
...
Apply complete! Resources: 4 added, 0 changed, 0 destroyed.
Outputs:
loadbalancer-ip = ip_address

Sie haben ein Modul erstellt, das eine konfigurierbare Anzahl von Droplets und einen Load Balancer enthält, der automatisch so konfiguriert ist, dass er deren ein- und ausgehenden Datenverkehr verwaltet.

Bereitgestellte Ressourcen umbenennen

Im vorherigen Abschnitt haben Sie das von Ihnen definierte Modul bereitgestellt und es „Gruppe“ genannt. Wenn Sie den Namen ändern möchten, reicht es nicht aus, den Modulaufruf einfach umzubenennen. Dadurch werden die Ressourcen von Terraform gelöscht und neu erstellt, was zu erheblichen Ausfallzeiten führt.

Zum Beispiel, main.tf Öffnen Sie die Datei zur Bearbeitung durch Ausführen von:

nano main.tf

Benennen Sie das Gruppenmodul wie angegeben in group_renamed um:

module "groups_renamed" {
source = "./modules/droplet-lb"
droplet_count = 3
group_name = "group1"
}
output "loadbalancer-ip" {
value = module.groups_renamed.lb_ip
}

Speichern und schließen Sie die Datei. Initialisieren Sie anschließend das Projekt erneut:

terraform init

Jetzt können Sie das Projekt planen:

terraform plan -var "do_token=${DO_PAT}"

Die Ausgabe wird lang sein, sieht aber in etwa so aus:

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] will be destroyed
...
# module.groups_renamed.digitalocean_droplet.droplets[0] will be created
...

Terraform erfordert, dass bestehende Instanzen gelöscht und neue erstellt werden. Dies ist destruktiv und unnötig und kann zu unbeabsichtigten Abstürzen führen.

Alternativ können Sie Terraform anweisen, die alten Ressourcen mithilfe des migrierten Blocks unter dem neuen Namen zu migrieren. Öffnen Sie die Datei main.tf zum Bearbeiten und fügen Sie die folgenden Zeilen am Ende der Datei hinzu:

moved {
from = module.groups
to = module.groups_renamed
}

Wenn Sie fertig sind, speichern und schließen Sie die Datei.

Jetzt können Sie das Projekt planen:

terraform plan -var "do_token=${DO_PAT}"

Wenn Sie in main.tf mit dem verschobenen Block programmieren, möchte Terraform die Ressourcen verschieben, anstatt sie neu zu erstellen:

OutputTerraform will perform the following actions:
# module.groups.digitalocean_droplet.droplets[0] has moved to module.groups_renamed.digitalocean_droplet.droplets[0]
...
# module.groups.digitalocean_droplet.droplets[1] has moved to module.groups_renamed.digitalocean_droplet.droplets[1]
...

Mobile Ressourcen ändern im Terraform-Modus ihren Standort, was bedeutet, dass die eigentlichen Cloud-Ressourcen nicht verändert, zerstört oder neu erstellt werden.

Da Sie die Konfiguration im nächsten Schritt wesentlich ändern werden, aktualisieren Sie die bereitgestellten Ressourcen mit folgendem Befehl:

terraform destroy -var "do_token=${DO_PAT}"

Als Sie gefragt wurden, Ja Eingabe. Die Ausgabe endet mit:

Output...
Destroy complete! Resources: 4 destroyed.

In diesem Abschnitt haben Sie Ressourcen in Ihrem Terraform-Projekt umbenannt, ohne sie zu löschen. Nun werden Sie mithilfe von `for_each` und `count` mehrere Instanzen eines Moduls aus demselben Code bereitstellen.

Bereitstellung mehrerer Modulinstanzen

In diesem Abschnitt verwenden Sie count und for_each, um das droplet-lb-Modul mit Anpassungen mehrfach bereitzustellen.

 Zählen

Eine Möglichkeit, mehrere Instanzen eines Moduls gleichzeitig bereitzustellen, besteht darin, dem Parameter `count`, der für jedes Modul automatisch verfügbar ist, eine Anzahl zu übergeben. Öffnen Sie `main.tf` zum Bearbeiten:

nano main.tf

Ändern Sie es wie folgt, indem Sie die bestehende Ausgabedefinition und den verschobenen Block löschen:

module "groups" {
source = "./modules/droplet-lb"
count = 3
droplet_count = 3
group_name = "group1-${count.index}"
}

Indem Sie die Anzahl auf 3 setzen, weisen Sie Terraform an, das Modul dreimal bereitzustellen, jeweils mit einem anderen Gruppennamen. Speichern und schließen Sie die Datei anschließend.

Planen Sie die Bereitstellung durch Ausführen von:

terraform plan -var "do_token=${DO_PAT}"

Die Ausgabe wird lang sein und folgendermaßen aussehen:

Output...
Terraform used the selected providers to generate the following execution plan. Resource actions are
indicated with the following symbols:
+ create
Terraform will perform the following actions:
# module.groups[0].digitalocean_droplet.droplets[0] will be created
...
# module.groups[0].digitalocean_droplet.droplets[1] will be created
...
# module.groups[0].digitalocean_droplet.droplets[2] will be created
...
# module.groups[0].digitalocean_loadbalancer.www-lb will be created
...
# module.groups[1].digitalocean_droplet.droplets[0] will be created
...
# module.groups[1].digitalocean_droplet.droplets[1] will be created
...
# module.groups[1].digitalocean_droplet.droplets[2] will be created
...
# module.groups[1].digitalocean_loadbalancer.www-lb will be created
...
# module.groups[2].digitalocean_droplet.droplets[0] will be created
...
# module.groups[2].digitalocean_droplet.droplets[1] will be created
...
# module.groups[2].digitalocean_droplet.droplets[2] will be created
...
# module.groups[2].digitalocean_loadbalancer.www-lb will be created
...
Plan: 12 to add, 0 to change, 0 to destroy.
...

Terraform erklärt in der Ausgabe, dass jede der drei Modulinstanzen über drei Droplets und einen zugehörigen Load Balancer verfügt.

Verwendung von for_each

Sie können for_each für Module verwenden, wenn Sie eine komplexere Anpassung der Instanzen benötigen oder wenn die Anzahl der Instanzen von Daten Dritter (oft als Map bereitgestellt) abhängt, die beim Schreiben des Codes nicht bekannt sind.

Nun definieren Sie eine Zuordnung, die die Gruppennamen der Anzahl der Droplets zuordnet und darauf basierend Droplet-LB-Instanzen implementiert. Öffnen Sie main.tf zur Bearbeitung durch Ausführen von:

nano main.tf

Ändern Sie die Datei wie folgt:

variable "group_counts" {
type = map
default = {
"group1" = 1
"group2" = 3
}
}
module "groups" {
source = "./modules/droplet-lb"
for_each = var.group_counts
droplet_count = each.value
group_name = each.key
}

Zuerst definieren Sie eine Map namens `group_counts`, die die Anzahl der Tröpfchen in einer bestimmten Gruppe enthält. Anschließend rufen Sie das Modul `droplet-lb` auf und geben an, dass die `for_each`-Schleife auf `var.group_counts`, der zuvor definierten Map, ausgeführt werden soll. `droplet_count` erwartet `each.value`, den aktuellen Paarwert, der die Anzahl der Tröpfchen in der aktuellen Gruppe angibt. `group_name` erwartet den Gruppennamen.

Wenn Sie fertig sind, speichern und schließen Sie die Datei.

Versuchen Sie, die Konfiguration anzuwenden, indem Sie Folgendes ausführen:

terraform plan -var "do_token=${DO_PAT}"

Die Ausgabe zeigt die Details der Terraform-Aktionen zur Erstellung dieser beiden Gruppen mit Droplets und Load Balancern:

Output...
Terraform used the selected providers to generate the following execution plan. Resource actions are
indicated with the following symbols:
+ create
Terraform will perform the following actions:
# module.groups["group1"].digitalocean_droplet.droplets[0] will be created
...
# module.groups["group1"].digitalocean_loadbalancer.www-lb will be created
...
# module.groups["group2"].digitalocean_droplet.droplets[0] will be created
...
# module.groups["group2"].digitalocean_droplet.droplets[1] will be created
...
# module.groups["group2"].digitalocean_droplet.droplets[2] will be created
...
# module.groups["group2"].digitalocean_loadbalancer.www-lb will be created
...

An diesem Punkt haben Sie count und for_each verwendet, um mehrere benutzerdefinierte Instanzen eines Moduls aus demselben Code bereitzustellen.

Ergebnis

In diesem Tutorial haben Sie Terraform-Module erstellt und implementiert. Sie haben Module verwendet, um logisch zusammengehörige Ressourcen zu gruppieren und sie so anzupassen, dass mehrere Instanzen einer zentralen Codedefinition bereitgestellt werden können. Außerdem haben Sie Ausgaben verwendet, um die Eigenschaften der Ressourcen im Modul anzuzeigen.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

Das könnte Ihnen auch gefallen