Wie man ein Terraform-Projekt strukturiert

Einführung

Die richtige Organisation von Terraform-Projekten basierend auf ihrem Zweck und der erwarteten Komplexität ist wichtig, um die Maintainabilität und die Erweiterbarkeit zu gewährleisten. Eine systematische Methode zur organisch codierung ist notwendig, damit das Projekt skalar bleibt während der Deployment und für Sie und Ihre Teammitglieder nutzbar bleibt. In diesem Tutorial lernen Sie, wie Sie Terraform-Projekte nach ihrem allgemeinen Zweck und Komplexitätstrukturieren. Dann erstellen Sie ein Projekt mit den mehr als üblichen Features von Terraform: Variablen, lokalen Variable, Datenquellen und Provisionern. Schließlich wird Ihr Projekt einen Ubuntu 20.04 Server (Droplett) auf DigitalOcean deployen, eine Apache Web-Server installieren und Ihren Domainnamen zum Web-Server hinweisen.

Voraussetzungen

Hinweis: Dieser Leitfaden wurde speziell mit Terraform 1.0.2 getestet.

Verstehen der Struktur eines Terraform-Projekts

In diesem Abschnitt lernen Sie, was Terraform als Projekt definiert, wie Sie die Infrastruktur-Code strukturieren können und wann sie welchen Ansatz wählen sollen. Sie erfahren auch mehr über Terraforms Workspaces, was sie tun und wie Terraform den Zustand speichert.

Eine Ressource ist eine Entität eines Cloud-Dienstes (zum Beispiel ein DigitalOcean Droplet), die in Terraform-Code festgelegt wird und nach bestimmten und abstrakten Eigenschaften erstellt wird. Mehrere Ressourcen bilden mit ihren miteinander verbundenen Verbindungen eine Infrastruktur.

Terraform verwendet eine speziell entwickelte Programmiersprache, die Hashicorp Konfigurationssprache (HCL) genannt ist. HCL-Code wird normalerweise in Dateien gespeichert, die die Erweiterung tf haben. Ein Terraform-Projekt ist jeder Ordner, der durch das init-Kommando initialisiert wurde, um Terraforms Caches zu setzen und einen lokalen Zustand zu erstellen.

Terraform Zustand ist das Mechanismus, mit dem es den tatsächlich in der Cloud deployierten Ressourcen aufzeichnet. Der Zustand wird in Backends (lokal auf einem Disk oder remote auf einem Dateistorage-Clouddienst oder speziellen Zustandsmanagementsoftware) gespeichert, um optimale Redundanz und Reliabilität zu gewährleisten. Sie können mehr über verschiedene Backends in der Terraform-Dokumentation lesen.

Projekt Arbeitsräume erlauben es dir, mehrere Zustände in der gleichen Backend-Konfiguration zu haben, die an die gleiche Konfiguration gebunden sind. Dadurch können Sie mehrere unterschiedliche Instanzen derselben Infrastruktur deployieren. Jeder Projekt beginnt mit einem Arbeitsraum namens default. Dieser wird verwendet, wenn du keinen anderen explizit erstellen oder wechseln hast.

Module in Terraform (analog zu Bibliotheken in anderen Programmiersprachen) sind parametrierte Code-Container, die mehrere Ressourcendeklarationen enthalten. Sie erlauben dir, einen gemeinsamen Teil deiner Infrastruktur abstrakter zu machen und später mit unterschiedlichen Eingaben wiederzuverwenden.

Eine Terraform-Projekt kann auch externes Code-Dateien enthalten, um dynamische Dateneingaben für die Ressourcendeklarationen zu verwenden, die eine JSON-Ausgabe einer CLI-Befehle parsen und ihr für die Ressourcendeklarationen anbieten. Im Tutorial werden Sie dies mit einem Python-Skript machen.

Nachdem du was ein Terraform-Projekt ausmacht, lass uns zwei allgemeine Ansätze zur Strukturierung von Terraform-Projekten überprüfen.

Einfache Struktur

Eine einfache Struktur ist für kleine und Testprojekte geeignet, die wenige unterschiedliche Ressourcen und Variablen aufweisen. Sie verfügt über wenige Konfigurationsdateien, normalerweise eine pro Ressourcentyp (oder mehrere Hilfsdateien zusammen mit einer Hauptdatei), und keine benutzerdefinierten Module, weil die meisten Ressourcen einzigartig sind und nicht genug existieren, um generalisiert und wiederverwendet zu werden. An dieser Stelle gefolgt von diesem wird der größte Teil des Codes in derselben Verzeichnisdatei gespeichert, nebeneinander. Diese Projekte haben oft nur wenige Variablen (wie beispielsweise einen API-Schlüssel für den Zugriff auf den Cloud-Dienst) und können dynamische Dateninput-Funktionen und andere Features von Terraform und HCL verwenden, obwohl dies nicht der Hauptanwendungsbereich ist.

Als Beispiel für die Dateistruktur dieser Herangehensweise sehen Sie am Ende des folgenden Tutorials, was das Projekt, das Sie aufbauen, aussieht:

.
└── tf/
    ├── versions.tf
    ├── variables.tf
    ├── provider.tf
    ├── droplets.tf
    ├── dns.tf
    ├── data-sources.tf
    └── external/
        └── name-generator.py

da das Projekt einen Apache-Web-Server-Droplet einrichten und DNS-Einträge setzen wird, werden die Definitionen der Projevariablen, der DigitalOcean Terraform-Anbieter, das Droplet und die DNS-Einträge in ihrer jeweiligen Datei gespeichert. Die minimal erforderlichen Versionen von Terraform und dem DigitalOcean-Anbieter werden in versions.tf angegeben, während das Python-Skript, das dem Droplet einen Namen geben wird (und als dynamische Datenquelle in data-sources.tf verwendet wird), im Verzeichnis external gespeichert wird, um es von der HCL-Datei zu trennen.

Complex Structure

Entgegen der einfachen Struktur ist dieser Ansatz für große Projekte geeignet, die klar definierte Unterverzeichnisse mit mehreren Modulen unterschiedlicher Komplexität enthalten, zusätzlich zum üblichen Code. Diese Module können voneinander abhängen. In Kombination mit Versionskontrollsystemen können diese Projekte umfassend Arbeitsumgebungen nutzen. Dieser Ansatz ist für größere Projekte geeignet, die mehrere Apps verwalten und dabei so viel wie möglich Code wiederverwenden.

Entwicklung, Staging, Quality Assurance und Produktions-Infrastruktur-Instanzen können ebenfalls unter demselben Projekt in verschiedenen Verzeichnissen untergebracht werden, indem sie auf gemeinsame Module zurückgreifen, wodurch doppelter Code eliminiert und das Projekt zur zentralen Quelle der Wahrheit wird. Hier ist die Dateistruktur eines Beispielprojekts mit einer komplexeren Struktur, das mehrere Deployment-Apps, Terraform-Module und Ziel-Cloud-Umgebungen enthält:

.
└── tf/
    ├── modules/
    │   ├── network/
    │   │   ├── main.tf
    │   │   ├── dns.tf
    │   │   ├── outputs.tf
    │   │   └── variables.tf
    │   └── spaces/
    │       ├── main.tf
    │       ├── outputs.tf
    │       └── variables.tf
    └── applications/
        ├── backend-app/
        │   ├── env/
        │   │   ├── dev.tfvars
        │   │   ├── staging.tfvars
        │   │   ├── qa.tfvars
        │   │   └── production.tfvars
        │   └── main.tf
        └── frontend-app/
            ├── env/
            │   ├── dev.tfvars
            │   ├── staging.tfvars
            │   ├── qa.tfvars
            │   └── production.tfvars
            └── main.tf

Diesen Ansatz wird in der Serie Wie man Infrastruktur mit Terraform verwaltet weiter erforscht.

Sie wissen nun, was ein Terraform-Projekt ist, wie es am besten gemäß der wahrgenommenen Komplexität strukturiert werden sollte und welche Rolle Terraform-Arbeitsumgebungen spielen. In den nächsten Schritten erstellen Sie ein Projekt mit einer einfachen Struktur, das einen Droplet mit einer installierten Apache-Webserver und DNS-Einträgen für Ihre Domain bereitstellt. Sie initialisieren zunächst Ihr Projekt mit dem DigitalOcean-Provider und Variablen und definieren dann den Droplet, eine dynamische Datenquelle, um seinen Namen bereitzustellen, sowie einen DNS-Eintrag für die Bereitstellung.

Schritt 1 — Einrichtung Ihres Anfangsprojekts

In diesem Abschnitt fügen Sie den DigitalOcean Terraform-Provider zu Ihrem Projekt hinzu, definieren Sie die Projektvariablen und deklarieren Sie eine DigitalOcean-Provider-Instanz, damit Terraform sich mit Ihrem Konto verbinden kann.

Fangen Sie an, indem Sie ein Verzeichnis für Ihr Terraform-Projekt mit dem folgenden Befehl erstellen:

  1. mkdir ~/apache-droplet-terraform

Navigieren Sie zu ihm:

  1. cd ~/apache-droplet-terraform

Da dieses Projekt dem einfachen Strukturierungsansatz folgt, speichern Sie den Provider, die Variablen, den Droplet und den DNS-Record-Code in separate Dateien, gemäß der Dateistruktur aus dem vorherigen Abschnitt. Zuerst müssen Sie den DigitalOcean Terraform-Provider zu Ihrem Projekt als erforderlichen Provider hinzufügen.

Erstellen Sie eine Datei namens versions.tf und öffnen Sie sie zum Bearbeiten, indem Sie ausführen:

  1. nano versions.tf

Fügen Sie die folgenden Zeilen hinzu:

~/apache-droplet-terraform/versions.tf
terraform {
  required_providers {
    digitalocean = {
      source = "digitalocean/digitalocean"
      version = "~> 2.0"
    }
  }
}

In diesem terraform-Block listen Sie die erforderlichen Provider (DigitalOcean, Version 2.x) auf. Wenn Sie fertig sind, speichern und schließen Sie die Datei.

Dann definieren Sie die Variablen, die Ihr Projekt offenzulegen wird, in der Datei variables.tf, indem Sie dem Ansatz folgen, verschiedene Ressourcentypen in separate Code-Dateien zu speichern:

  1. nano variables.tf

Fügen Sie die folgenden Variablen hinzu:

~/apache-droplet-terraform/variables.tf
variable "do_token" {}
variable "domain_name" {}

Speichern und schließen Sie die Datei.

Die Variable do_token wird Ihren DigitalOcean Personal Access Token halten und domain_name wird Ihren gewünschten Domainnamen angeben. Der部署te Droplet wird über die SSH-Schlüssel automatisch installiert, die durch die SSH-Fingerabdrückung identifiziert werden.

Nächstes, definieren wir den DigitalOcean-Anbieterinstanz für dieses Projekt. Sie werden es in einer Datei namens provider.tf speichern. Erstellen und öffnen Sie diese Datei, indem Sie ausführen:

  1. nano provider.tf

Fügen Sie den Anbieter hinzu:

~/apache-droplet-terraform/provider.tf
provider "digitalocean" {
  token = var.do_token
}

Wenn Sie fertig sind, speichern und beenden Sie die Bearbeitung. Sie haben den digitalocean-Anbieter definiert, der dem zuvor in provider.tf angegebenen erforderlichen Anbieter entspricht, und seinen Token auf dieVariable gesetzt, die während der Laufzeit bereitgestellt wird.

In diesem Schritt haben Sie ein Verzeichnis für Ihr Projekt erstellt, den DigitalOcean-Anbieter angefordert, Projektvariablen deklariert und die Verbindung zu einer DigitalOcean-Anbieterinstanz eingerichtet, um einen Authentifizierungstoken zu verwenden, der später bereitgestellt wird. Jetzt werden Sie ein Skript schreiben, das dynamische Daten für Ihre Projektdefinitionen generieren wird.

Schritt 2 — Erstellung eines Python-Skripts für dynamische Daten

Bevor Sie die Definition des Droplet fortsetzen, erstellen Sie ein Python-Skript, das den Namen des Droplet dynamisch generiert und eine Datenquelleressource für die Parsing声明. Der Name wird durch die Konkatenation einer Konstanten Zeichenfolge (web) mit der aktuellen lokalen Maschinenzeit im UNIX epoch Format erstellt. Ein Namensskript kann nützlich sein, wenn mehrere Droplet basierend auf einem Namensschema erstellt werden, um sie leichter unterscheiden zu können.

Sie werden das Skript in einer Datei namens name-generator.py in einem Verzeichnis namens external speichern. Erstellen Sie das Verzeichnis, indem Sie ausführen:

  1. mkdir external

Das external Verzeichnis befindet sich im Wurzelverzeichnis Ihres Projekts und wird Dateien speichern, die kein HCL-Code sind, wie das Python-Skript, das Sie schreiben werden.

Erstellen name-generator.py unter external und öffnen Sie es zum Bearbeiten:

  1. nano external/name-generator.py

Fügen Sie folgenden Code hinzu:

external/name-generator.py
import json, time

fixed_name = "web"
result = {
  "name": f"{fixed_name}-{int(time.time())}",
}

print(json.dumps(result))

Dieses Python-Skript importiert die Module json und time, erklärt eine dictionary namens result und setzt den Wert der Schluessel name auf eine interpolierte Zeichenfolge, die die fixed_name mit der aktuellen UNIX-Zeit der Maschine, auf der es läuft, kombiniert. Anschließend wird result in JSON umgewandelt und auf stdout ausgegeben. Die Ausgabe wird jedes Mal, wenn das Skript ausgeführt wird, unterschiedlich sein:

Output
{"name": "web-1597747959"}

Wenn du fertig bist, speichere und schließe die Datei.

Hinweis: Große und komplexe strukturierte Projekte erfordern mehr Überlegungen bezüglich der Erstellung und Nutzung von externen Datenquellen, insbesondere im Hinblick auf Portierbarkeit und Fehlerbehandlung. Terraform erwartet, dass das ausgeführte Programm einen für Menschen lesbare Fehlermeldung in stderr schreibt und mit einem nicht-Null-Status gnadenvoll beendet, was in diesem Schritt aufgrund der Einfachheit der Aufgabe nicht dargestellt ist. Zusätzlich erwartet es, dass das Programm keine Nebenwirkungen hat, sodass es beliebig oft neu gestartet werden kann.

Weitere Informationen über die Erwartungen von Terraform bezüglich der Datenquellen findest du in den offiziellen Dokumentationen zu Datenquellen.

Nun, da der Skript bereit ist, kannst du die Datenquelle definieren, die die Daten aus dem Skript ziehen wird. Du speicherst die Datenquelle in einer Datei namens data-sources.tf im Stammverzeichnis deines Projekts gemäß der einfachen Strukturierungsmethode.

Erstelle diese Datei zum Bearbeiten mit dem Befehl:

  1. nano data-sources.tf

Füge die folgende Definition hinzu:

~/apache-droplet-terraform/data-sources.tf
data "external" "droplet_name" {
  program = ["python3", "${path.module}/external/name-generator.py"]
}

Speichere und schließe die Datei.

Diese Datenquelle heißt droplet_name und führt den Skript name-generator.py mit Python 3 aus, der im gerade erstellten Verzeichnis external liegt. Es parsed automatisch seine Ausgabe und stellt die deserialisierten Daten unter seinem Attribut result bereit, um sie in anderen Ressourcendefinitionen zu verwenden.

Nach der Definition der Datenquelle kannst du nun die Droplet definieren, auf der Apache ausgeführt wird.

Schritt 3 — Definieren des Droplet

In diesem Schritt schreiben Sie die Definition des Droplet-Ressourcens und speichern sie in einem Code-Datei unter dem Namen ein, der aus den dynamischen Datenquellen hervorgeht, wie im letzten Schritt festgelegt wurde. Der Name wird jedoch bei jeder Deployment unterschiedlich sein.

Erstellen und öffnen Sie die Datei droplets.tf für die Bearbeitung:

  1. nano droplets.tf

Fügen Sie folgende Droplet-Ressourcendefinition hinzu:

~/apache-droplet-terraform/droplets.tf
data "digitalocean_ssh_key" "ssh_key" {
  name = "your_ssh_key_name"
}

resource "digitalocean_droplet" "web" {
  image  = "ubuntu-20-04-x64"
  name   = data.external.droplet_name.result.name
  region = "fra1"
  size   = "s-1vcpu-1gb"
  ssh_keys = [
    data.digitalocean_ssh_key.ssh_key.id
  ]
}

Sie erstellen zunächst eine Ressource für einen DigitalOcean SSH-Key namens ssh_key, die das SSH-Key von Ihrem Konto nach dessen Namen abfragt. Stellen Sie sicher, dass Sie die angezeigte Zeichenfolge mit dem Namen Ihres SSH-Keys ersetzen.

Danach definieren Sie eine Droplet-Ressourcen, die web genannt wird. Der tatsächliche Name im Cloude ist unterschiedlich, weil er vom droplet_name externen Datenquelle abgerufen wird. Um jedes Mal, wenn das Droplet deployiert wird, das SSH-Key zu bootstrappen, wird die ID des ssh_key als ssh_keys Parameter übergeben, damit DigitalOcean weiß, welches Key angewendet werden soll.

Für jetzt ist dies alles, was Sie konfigurieren müssen, was auf droplet.tf betrifft, also speichern und schließen Sie die Datei, wenn Sie fertig sind.

Sie schreiben nun die Konfiguration für die DNS-Einträge, die Ihr Domänenname zu dem gerade definierten Droplet verlinken werden sollen.

Schritt 4 — Definieren von DNS-Einträgen

Der letzte Schritt im Prozess ist die Konfiguration des DNS-Eintrages für den Droplet aus deinem Domänennamen herzustellen.

Sie speichern die DNS-Konfiguration in einer Datei namens dns.tf an, weil sie ein separates Ressourcen-Typ ist als die anderen Schritte, die Sie zuvor erstellt haben. Erstellen und öffnen Sie sie für die Bearbeitung:

  1. nano dns.tf

Fügen Sie folgende Zeilen hinzu:

~/apache-droplet-terraform/dns.tf
resource "digitalocean_record" "www" {
  domain = var.domain_name
  type   = "A"
  name   = "@"
  value  = digitalocean_droplet.web.ipv4_address
}

Dieser Code definiert einen DigitalOcean DNS-Eintrag bei Ihrem Domainnamen (über die Variable übergeben), vom Typ A. Der Eintrag hat einen Namen von @, der als Platzhalter zum Domänennamen selbst und mit dem IP-Adressen des Droplets als Wert verwendet wird. Sie können den name Wert zu einem anderen ersetzen, was dann eine Unterdomäne erstellen wird.

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

Nun hast du die Droplet konfiguriert, das Name-Generator-Datensource und einen DNS-Eintrag. Du gehst nun weiter zur Deployment des Projekts in der Cloud.

Schritt 5 — Planen und Anwenden der Konfiguration

In diesem Abschnitt initialisierst du deinen Terraform-Projekt, deployst es ins Cloud-Netzwerk und prüfst dann, ob alles richtig bereitgestellt wurde.

Nachdem das Projektinfrastruktur vollständig definiert ist, alles was noch fehlt, ist es, es zu deployen und zu überprufen, ob alles korrekt bereitgestellt wurde.

  1. terraform init

Zunächst initialiseren Sie das Terraform-Projekt mit dem folgenden Befehl:

Output
Initializing the backend... Initializing provider plugins... - Finding digitalocean/digitalocean versions matching "~> 2.0"... - Finding latest version of hashicorp/external... - Installing digitalocean/digitalocean v2.10.1... - Installed digitalocean/digitalocean v2.10.1 (signed by a HashiCorp partner, key ID F82037E524B9C0E8) - Installing hashicorp/external v2.1.0... - Installed hashicorp/external v2.1.0 (signed by HashiCorp) Partner and community providers are signed by their developers. If you'd like to know more about provider signing, you can read about it here: https://www.terraform.io/docs/cli/plugins/signing.html Terraform has created a lock file .terraform.lock.hcl to record the provider selections it made above. Include this file in your version control repository so that Terraform can guarantee to make the same selections by default when you run "terraform init" in the future. 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 erhalten die folgende Ausgabe:

Sie können nun Ihr Droplet mit einem dynamisch generierten Namen und zugehörigem Domainnamen auf Ihrem DigitalOcean-Konto deployen.

  1. export DO_PAT="your_do_api_token"
  2. export DO_DOMAIN_NAME="your_domain"

Beginnen Sie damit, die Domänenname, die Fingerabdruck der SSH-Schlüssel und Ihr persönlicher Zugriffstoken als Umgebungsvariablen festlegen, sodass Sie nicht jedes Mal den Wert kopieren müssen, wenn Sie Terraform ausführen. Führen Sie die folgenden Befehle aus, indem Sie die hervorgehobenen Werte ersetzen:

Sie finden Ihren API-Token in Ihrem DigitalOcean-Kontrollpanel.

  1. terraform plan -var "do_token=${DO_PAT}" -var "domain_name=${DO_DOMAIN_NAME}"

Führen Sie den plan-Befehl mit den übergebenen Werten aus, um zu sehen, welche Schritte Terraform unternehmen würde, um das Projekt zu deployen:

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: Die Ausgabe wird ähnlich wie folgt sein: + resource "digitalocean_droplet" "web" { + backups = false + created_at = (known after apply) + disk = (known after apply) + id = (known after apply) + image = "ubuntu-20-04-x64" + ipv4_address = (known after apply) + ipv4_address_private = (known after apply) + ipv6 = false + ipv6_address = (known after apply) + locked = (known after apply) + memory = (known after apply) + monitoring = false + name = "web-1625908814" + price_hourly = (known after apply) + price_monthly = (known after apply) + private_networking = (known after apply) + region = "fra1" + resize_disk = true + size = "s-1vcpu-1gb" + ssh_keys = [ + "...", ] + status = (known after apply) + urn = (known after apply) + vcpus = (known after apply) + volume_ids = (known after apply) + vpc_uuid = (known after apply) } # digitalocean_droplet.web wird erstellt + resource "digitalocean_record" "www" { + domain = "your_domain'" + fqdn = (known after apply) + id = (known after apply) + name = "@" + ttl = (known after apply) + type = "A" + value = (known after apply) } Plan: 2 to add, 0 to change, 0 to destroy. ...

# digitalocean_record.www wird erstellt

  1. terraform apply -var "do_token=${DO_PAT}" -var "domain_name=${DO_DOMAIN_NAME}"

Die Zeilen, die mit einem grünen + beginnen, bedeuten, dass Terraform nach dem folgenden jedes der Ressourcen erstellen wird—was genau so sollte passieren, also können Sie apply die Konfiguration:

Output
Plan: 2 to add, 0 to change, 0 to destroy. Do you want to perform these actions? Terraform will perform the actions described above. Only 'yes' will be accepted to approve. Enter a value: `yes`

Antworten Sie mit yes, und Terraform will Ihre Droplet und die DNS-Einträge provisionieren:

Output
digitalocean_droplet.web: Creating... ... digitalocean_droplet.web: Creation complete after 33s [id=204432105] digitalocean_record.www: Creating... digitalocean_record.www: Creation complete after 1s [id=110657456] Apply complete! Resources: 2 added, 0 changed, 0 destroyed.

Terraform hat nun die部署te Ressourcen in seinem Zustand aufgenommen. Um zu bestätigen, dass die DNS-Einträge und die Droplet erfolgreich verbunden sind, kannst du die IP-Adresse des Droplet aus dem lokalen Zustand extrahieren und prüfen, ob sie mit den öffentlichen DNS-Einträgen für deine Domain übereinstimmt. Führe den folgenden Befehl aus, um die IP-Adresse zu erhalten:

  1. terraform show | grep "ipv4"

Du erhälst die IP-Adresse deines Droplet:

Output
ipv4_address = "your_Droplet_IP" ...

Du kannst die öffentlichen A-Einträge über den Befehl ausgeben:

  1. nslookup -type=a your_domain | grep "Address" | tail -1

Der Ausgabestrom zeigt die IP-Adresse an, zu der der A-Eintrag zeigt:

Output
Address: your_Droplet_IP

Sie sind identisch, was erwartet wurde, was bedeutet, dass das Droplet und der DNS-Eintrag erfolgreich bereitgestellt wurden.

Um die Änderungen in der nächsten Schritt zu vollziehen, zerstöre die bereitgestellten Ressourcen, indem du den Befehl ausführen:

  1. terraform destroy -var "do_token=${DO_PAT}" -var "domain_name=${DO_DOMAIN_NAME}"

Wenn du fragst, gebe du yes ein, um fortzufahren.

In diesem Schritt hast du deine Infrastruktur erstellt und auf deinem DigitalOcean-Konto angewendet. Nun wirst du sie ändern, um den Apache-Webserver automatisch auf dem bereitgestellten Droplet mit Hilfe von Terraform-Bereitstellern zu installieren.

Schritt 6 — Code mit Provisionern ausführen

Nun werden Sie die Installation des Apache-Webservers auf Ihrem bereitgestellten Droplet durch Verwendung des remote-exec-Bereitstelllers für benutzerdefinierte Befehle einrichten.

Terraform provisionern können zum Ausführen spezifischer Aktionen auf erstellten Remote-Ressourcen (durch den remote-exec Provisioner) oder auf dem lokalen Maschinen benutzt werden, auf dem die Code ausgeführt wird (mit dem local-exec Provisioner). Wenn ein Provisioner fehlerhaft ist, wird der Knoten als beschädigt in der aktuellen Status markiert, was bedeutet, dass er bei der nächsten Runde gelöscht und wieder erstellt wird.

Um mit einem bereitgestellten Droplett verbinden zu können, braucht Terraform das privaten SSH-Schlüssel des Droplet, das Sie zuvor festlegen haben. Die beste Methode, die Position des privaten Schlüssels anzugeben, ist durch Variablen, daher öffnen Sie variables.tf für Bearbeitung:

  1. nano variables.tf

Fügen Sie die unterstrichente Zeile hinzu:

~/apache-droplet-terraform/variables.tf
variable "do_token" {}
variable "domain_name" {}
variable "private_key" {}

Sie haben jetzt eine neue Variable hinzugefügt, die private_key genannt ist, zu Ihrem Projekt. Speichern und schließen Sie die Datei.

Nächstes steht die Erweiterung der Droplet-Konfiguration mit den angezeigten Zeilen zu:Öffnen Sie droplets.tf für Bearbeitung, indem Sie folgenden Befehl ausführen:

  1. nano droplets.tf

Erweiten Sie das existierende Code-Block mit den unterstrichenten Zeilen:

~/apache-droplet-terraform/droplets.tf
data "digitalocean_ssh_key" "ssh_key" {
  name = "your_ssh_key_name"
}

resource "digitalocean_droplet" "web" {
  image  = "ubuntu-20-04-x64"
  name   = data.external.droplet_name.result.name
  region = "fra1"
  size   = "s-1vcpu-1gb"
  ssh_keys = [
    data.digitalocean_ssh_key.ssh_key.id
  ]

  connection {
    host        = self.ipv4_address
    user        = "root"
    type        = "ssh"
    private_key = file(var.private_key)
    timeout     = "2m"
  }

  provisioner "remote-exec" {
    inline = [
      "export PATH=$PATH:/usr/bin",
      # Install Apache
      "apt update",
      "apt -y install apache2"
    ]
  }
}

Der connection Block definiert wie Terraform sich mit Ziel Droplet verbinden soll. Der provisioner Block enthält die Anweisungen im Array inline, die nach der Provisionierung ausgeführt werden sollen, also das Updaten des Paketmanager-Cache und die Installation von Apache. Speichern und verlassen Sie die Datei, wenn Sie fertig sind.

Sie können auch einen temporaren Umgebungsvariable für den Pfad des privaten Schlüssels erstellen:

  1. export DO_PRIVATE_KEY="private_key_location"

Bemerkung: Die privaten Schlüssel sowie alle anderen Dateien, die Sie innerhalb von Terraform laden möchten, müssen im Projekt enthalten sein. Sie können sich den Tutorial zur Konfiguration von SSH-Key-Authentikation auf einem Linux-Server ansehen für mehr Informationen über die Einrichtung eines SSH-Schlüssels auf Ubuntu 20.04 oder anderen Distributionen.

Versuchen Sie, die Konfiguration erneut anzuwenden:

  1. terraform apply -var "do_token=${DO_PAT}" -var "domain_name=${DO_DOMAIN_NAME}" -var "private_key=${DO_PRIVATE_KEY}"

Geben Sie bei der Aufforderung yes ein. Sie erhalten eine Ausgabe ähnlich der vorherigen, aber mit längeren Ausgaben aus dem remote-exec Provisioner:

Output
digitalocean_droplet.web: Creating... digitalocean_droplet.web: Still creating... [10s elapsed] digitalocean_droplet.web: Still creating... [20s elapsed] digitalocean_droplet.web: Still creating... [30s elapsed] digitalocean_droplet.web: Provisioning with 'remote-exec'... digitalocean_droplet.web (remote-exec): Connecting to remote host via SSH... digitalocean_droplet.web (remote-exec): Host: ... digitalocean_droplet.web (remote-exec): User: root digitalocean_droplet.web (remote-exec): Password: false digitalocean_droplet.web (remote-exec): Private key: true digitalocean_droplet.web (remote-exec): Certificate: false digitalocean_droplet.web (remote-exec): SSH Agent: false digitalocean_droplet.web (remote-exec): Checking Host Key: false digitalocean_droplet.web (remote-exec): Connected! ... digitalocean_droplet.web: Creation complete after 1m5s [id=204442200] digitalocean_record.www: Creating... digitalocean_record.www: Creation complete after 1s [id=110666268] Apply complete! Resources: 2 added, 0 changed, 0 destroyed.

Sie können nun zu Ihrem Domänennamen in einem Webbrowser navigieren und sehen das Standard-Apache-Willkommensseite an.

Dies bedeutet, dass Apache erfolgreich installiert wurde und Terraform die richtigen Ressourcen bereitstellte.

Um die部署ierte Ressourcen zu zerstören, führen Sie folgendes Kommando aus und geben Sie bei der Aufforderung yes ein:

  1. terraform destroy -var "do_token=${DO_PAT}" -var "domain_name=${DO_DOMAIN_NAME}" -var "private_key=${DO_PRIVATE_KEY}"

Sie haben jetzt einen kleinen Terraform-Projekt mit einer einfachen Struktur abgeschlossen, das das Apache-Web-Server auf einem Droplet installiert und die DNS-Einträge für die gewünschte Domain festlegt hat.

Konklusion

Sie haben zwei allgemeine Ansätze zur Strukturierung Ihrer Terraform-Projekte je nach Komplexität gelernt. Nach dem einfachen Strukturierungsansatz und der Verwendung des remote-exec-Provisioners zur Ausführung von Befehlen haben Sie dann einen Droplet mit Apache und DNS-Records für Ihre Domain bereitgestellt.

Als Referenz hier die Dateistruktur des Projekts, das Sie in diesem Tutorial erstellt haben:

.
└── tf/
    ├── versions.tf
    ├── variables.tf
    ├── provider.tf
    ├── droplets.tf
    ├── dns.tf
    ├── data-sources.tf
    └── external/
        └── name-generator.py

Die von Ihnen definierten Ressourcen (der Droplet, der DNS-Record und die dynamische Datenquelle, der DigitalOcean-Provider und Variablen) sind je in eigenen separaten Dateien gespeichert, entsprechend der einfachen Projektstruktur, die im ersten Abschnitt dieses Tutorials beschrieben wurde.

Weitere Informationen über Terraform-Provisioner und deren Parameter finden Sie in der offiziellen Dokumentation.

Dieses Tutorial ist Teil der Reihe How To Manage Infrastructure with Terraform. Die Reihe deckt eine Reihe von Terraform-Themen ab, von der ersten Installation von Terraform bis zur Verwaltung komplexer Projekte.

Source:
https://www.digitalocean.com/community/tutorials/how-to-structure-a-terraform-project