Wie man lastausgeglichene Webanwendungen auf DigitalOcean mit CDK für Terraform und TypeScript bereitstellt

Der Autor hat die Wikimedia Foundation ausgewählt, um im Rahmen des Write for Donations-Programms eine Spende zu erhalten.

Einführung

Infrastructure as Code (IaC) ist eine Praxis zur Automatisierung von Infrastruktur-Bereitstellung und -Änderungen durch die Definition der Ressourcenzustände und ihrer Beziehungen im Code. Die Ausführung dieses Codes erstellt oder ändert dann die tatsächlichen Ressourcen in der Cloud. IaC ermöglicht es Ingenieuren, ein IaC-Tool wie Terraform (von HashiCorp) zur Bereitstellung von Infrastruktur zu verwenden.

Mit IaC können Änderungen an Ihrer Infrastruktur denselben Codeüberprüfungsprozess durchlaufen wie Ihr Anwendungscode. Sie können den Code in Versionskontrolle (wie Git) speichern, um einen Verlauf des Zustands Ihrer Infrastruktur zu führen, und den Bereitstellungsprozess weiter automatisieren mit höherstufigen Tools wie einer selbstbedienungsfähigen internen Entwicklerplattform (IDP).

Terraform ist ein beliebtes plattformunabhängiges IaC-Tool aufgrund seiner breiten Unterstützung für viele Plattformen, einschließlich GitHub, Cloudflare und DigitalOcean. Die meisten Terraform-Konfigurationen werden mit einer deklarativen Sprache namens HashiCorp Configuration Language (HCL) geschrieben.

Das Cloud Development Kit für Terraform (CDKTF) ist ein Tool, das auf Terraform aufbaut und es ermöglicht, Infrastruktur mit einer vertrauten Programmiersprache (wie TypeScript, Python oder Go) anstelle von HCL zu definieren. Dieses Tool kann für Entwickler, die mit HCL nicht vertraut sind, eine flachere Lernkurve bieten und es Entwicklern ermöglichen, native Programmierfunktionen wie Schleifen, Variablen und Funktionen zu verwenden.

In diesem Tutorial beginnen Sie mit der Installation des Befehlszeilenschnittstellen-(CLI)-Tools cdktf. Anschließend erstellen Sie ein CDKTF-Projekt in TypeScript und definieren das Projekt mit zwei NGINX-Servern, die von einem Lastausgleicher ausbalanciert werden. Danach verwenden Sie cdktf, um die Infrastruktur bereitzustellen. Am Ende dieses Tutorials haben Sie ein CDKTF-Projekt, mit dem Sie Ihre Infrastruktur erweitern können.

Hinweis: Dieses Tutorial wurde mit CDKTF 0.11.2 und Terraform 1.2.2 getestet.

Voraussetzungen

Um dieses Tutorial abzuschließen, benötigen Sie:

Schritt 1 — Installation der cdktf-CLI

Um loszulegen, installieren Sie das Befehlszeilenwerkzeug cdktf.

Die cdktf-CLI ist als NPM-Paket verfügbar. Wenn Sie auf npmjs.com nach cdktf suchen, finden Sie zwei ähnlich benannte Pakete: cdktf und cdktf-cli.

Konzeptuell ist CDKTF eine Abstraktionsschicht über Terraform. Es besteht aus zwei Teilen:

  • Eine Bibliothek, die eine Reihe von sprachspezifischen Konstrukten (wie Funktionen und Klassen) zum Definieren von Infrastruktur enthält. Dieser Teil ist innerhalb des cdktf npm-Pakets gekapselt. Zum Beispiel können Sie die Verwendung der Klassen App und TerraformStack aus dem Paket cdktf im folgenden Beispielprojekt für CDKTF sehen:

    import { App, TerraformStack } from "cdktf";
    class APIStack extends TerraformStack {}
    const app = new App();
    new APIStack(app, "feature-x");
    app.synth();
    
  • Ein Adapter, der die Konstrukte innerhalb des CDKTF-Projekts analysiert und sie auf eine Reihe von JSON-Dokumenten reduziert, die dann genauso in Terraform eingebunden werden wie HCL. Dieser Adapter ist in ein CLI-Tool namens cdktf eingebettet, das vom Paket cdktf-cli bereitgestellt wird.

Um das CLI-Tool cdktf zu installieren, benötigen Sie das Paket cdktf-cli. Sie können dieses Paket global mit npm, yarn oder einem Paketmanager Ihrer Wahl installieren.

Um cdktf-cli mit npm zu installieren, führen Sie folgendes aus:

  1. npm install --global [email protected]

Hinweis: Es wird wahrscheinlich eine neuere Version des Pakets cdktf-cli nach der Veröffentlichung dieses Artikels geben. Sie können versuchen, dem Tutorial mit der neuesten Version zu folgen, indem Sie stattdessen npm install --global cdktf-cli@latest ausführen, seien Sie jedoch darauf vorbereitet, dass einige Ausgaben geringfügig abweichen können.

Alternativ können Sie Homebrew auf macOS oder Linux verwenden, um das cdktf CLI als Formel cdktf zu installieren:

  1. brew install cdktf

Um zu überprüfen, ob die Installation erfolgreich war, führen Sie den Befehl cdktf ohne Argumente aus:

  1. cdktf

Sie werden eine Ausgabe ähnlich der folgenden sehen:

Output
Please pass a command to cdktf, here are all available ones: cdktf Commands: cdktf init Create a new cdktf project from a template. cdktf get Generate CDK Constructs for Terraform providers and modules. cdktf convert Converts a single file of HCL configuration to CDK for Terraform. cdktf deploy [stacks...] Deploy the given stacks cdktf destroy [stacks..] Destroy the given stacks cdktf diff [stack] Perform a diff (terraform plan) for the given stack cdktf list List stacks in app. cdktf login Retrieves an API token to connect to Terraform Cloud. cdktf synth Synthesizes Terraform code for the given app in a directory. cdktf watch [stacks..] [experimental] Watch for file changes and automatically trigger a deploy cdktf output [stacks..] Prints the output of stacks cdktf debug Get debug information about the current project and environment cdktf completion generate completion script Options: --version Zeigt die Versionsnummer an --disable-logging Schreibt keine Protokolldateien. Unterstützt durch die Umgebungsvariable CDKTF_DISABLE_LOGGING. --disable-plugin-cache-env Setzt TF_PLUGIN_CACHE_DIR nicht automatisch. --log-level Welches Protokolllevel soll geschrieben werden. -h, --help Show help Options can be specified via environment variables with the "CDKTF_" prefix (e.g. "CDKTF_OUTPUT")

Die Ausgabe zeigt Ihnen die verfügbaren Befehle. Im Rest dieses Tutorials werden Sie Erfahrung darin sammeln, cdktf init, cdktf get, cdktf deploy und cdktf destroy zu verwenden.

Jetzt, da Sie die cdktf-CLI installiert haben, können Sie Infrastruktur definieren, indem Sie etwas TypeScript-Code schreiben.

Schritt 2 — Erstellen eines neuen CDKTF-Projekts

In diesem Schritt verwenden Sie die gerade installierte cdktf-CLI, um ein Grundgerüst für ein CDKTF-Projekt zu erstellen, auf dem Sie in den folgenden Schritten aufbauen werden.

Erstellen Sie ein Verzeichnis, das das CDKTF-Projekt beherbergen wird, indem Sie den folgenden Befehl ausführen:

  1. mkdir infra

Wechseln Sie dann in das neu erstellte Verzeichnis:

  1. cd infra/

Verwenden Sie den Befehl cdktf init, um ein CDKTF-Projektgerüst zu erstellen, auf dem Sie aufbauen werden:

  1. cdktf init --template=typescript --project-name=base --project-description="Base architecture" --local

CDKTF ermöglicht Entwicklern, Infrastruktur mithilfe von TypeScript, Python, Java, C# oder Go zu definieren. Die Option --template=typescript teilt cdktf mit, dieses CDKTF-Projekt mithilfe von TypeScript zu erstellen.

Terraform (und somit CDKTF) verfolgt die Ressourcen, die es verwaltet, indem es ihre Definitionen und Zustände in Dateien namens Terraform-Status-Dateien aufzeichnet. Die Option --local teilt CDKTF mit, diese Statusdateien lokal auf dem Computer, auf dem cdktf ausgeführt wird, zu speichern (jede Datei folgt der Benennungsstruktur terraform.<stack>.tfstate).

Nach Ausführung des Befehls kann die CLI Sie um Erlaubnis bitten, Absturzberichte an das CDKTF-Team zu senden, um ihnen bei der Verbesserung des Produkts zu helfen:

Output
? Do you want to send crash reports to the CDKTF team? See https://www.terraform.io/cdktf/create-and-deploy/configuration-file for more information (Y/n)

Geben Sie Y ein, wenn Sie zustimmen möchten, oder N, wenn Sie nicht einverstanden sind, und drücken Sie dann ENTER.

cdktf wird dann das Projektskelett erstellen und die Pakete installieren. Wenn das Projekt skaliert ist, sehen Sie eine Ausgabe ähnlich wie die folgende:

Output
Your cdktf typescript project is ready! cat help Print this message Compile: npm run get Import/update Terraform providers and modules (you should check-in this directory) npm run compile Compile typescript code to javascript (or "npm run watch") npm run watch Watch for changes and compile typescript in the background npm run build Compile typescript Synthesize: cdktf synth [stack] Synthesize Terraform resources from stacks to cdktf.out/ (ready for 'terraform apply') Diff: cdktf diff [stack] Perform a diff (terraform plan) for the given stack Deploy: cdktf deploy [stack] Deploy the given stack Destroy: cdktf destroy [stack] Destroy the stack Test: npm run test Runs unit tests (edit __tests__/main-test.ts to add your own tests) npm run test:watch Watches the tests and reruns them on change Upgrades: npm run upgrade Upgrade cdktf modules to latest version npm run upgrade:next Upgrade cdktf modules to latest "@next" version (last commit)

Sie sehen auch einige neue Dateien im Verzeichnis infra. Die wichtigsten Dateien sind cdktf.json und main.ts.

cdktf.json ist die Konfigurationsdatei für das CDKTF-Projekt. Wenn Sie die Datei öffnen, wird etwas Ähnliches wie folgt angezeigt:

cdktf.json
{
  "language": "typescript",
  "app": "npx ts-node main.ts",
  "projectId": "28c87598-4343-47a9-bb5d-8fb0e031c41b",
  "terraformProviders": [],
  "terraformModules": [],
  "context": {
    "excludeStackIdFromLogicalIds": "true",
    "allowSepCharsInLogicalIds": "true"
  }
}

Die Eigenschaft app definiert den Befehl, der ausgeführt wird, um den TypeScript-Code in Terraform-kompatibles JSON zu synthetisieren. Diese Eigenschaft zeigt an, dass main.ts der Einstiegspunkt in das CDKTF-Projekt ist.

Wenn Sie die Datei main.ts öffnen, sehen Sie etwas Ähnliches wie das Folgende:

main.ts
import { Construct } from "constructs";
import { App, TerraformStack } from "cdktf";

class MyStack extends TerraformStack {
  constructor(scope: Construct, name: string) {
    super(scope, name);

    // definieren Sie hier Ressourcen
  }
}

const app = new App();
new MyStack(app, "infra");
app.synth();

In der Sprache von CDKTF können eine Sammlung von verwandten Infrastrukturressourcen zu einem Stack gruppiert werden. Zum Beispiel können die Ressourcen, die eine API-Anwendung bilden, wie Droplets, Lastenausgleicher und DNS-Einträge, in einem einzelnen Stack namens APIStack gruppiert werden. Jeder Stack behält seinen eigenen Zustand bei und kann unabhängig von anderen Stacks bereitgestellt, geändert oder zerstört werden. Eine häufige Verwendung von Stacks besteht darin, einen Stack für die Produktion und einen separaten Stack für die Entwicklung zu haben.

Eine Anwendung ist ein Container für mehrere Stacks. Zum Beispiel kann eine Anwendung die Stacks verschiedener Microservices gruppieren.

Das im main.ts generierte CDKTF-Projektskelett enthält eine einzelne Stack-Klasse namens MyStack, die derzeit keine Ressourcen definiert. Eine Instanz von MyStack wird mit dem Namen infra erstellt, die innerhalb einer Anwendung namens app enthalten ist. In den folgenden Schritten werden Sie Infrastrukturressourcen im Konstruktor von MyStack definieren.

Nachdem das Projekt erstellt wurde, ist der nächste Schritt die Konfiguration des CDKTF-Projekts mit Providern.

Schritt 3 – Installation des DigitalOcean Providers

In diesem Schritt installieren Sie den DigitalOcean-Provider in das CDKTF-Projekt.

Provider sind Bibliotheken, die Anweisungen für Terraform (das von cdktf im Hintergrund verwendet wird) bereitstellen, wie Ressourcen bei Cloud-Anbietern, SaaS-Anbietern und anderen Plattformen, die Anwendungsprogrammierschnittstellen (APIs) bereitstellen, erstellt, aktualisiert und gelöscht werden können. Provider kapseln die Logik des Aufrufs dieser Upstream-APIs in Standardfunktionen, die Terraform aufrufen kann.

Zum Beispiel müssten Sie, wenn Sie einen neuen DigitalOcean-Droplet ohne Terraform erstellen wollten, eine POST-Anfrage an den /v2/droplets-Endpunkt der DigitalOcean-API senden. Mit Terraform installieren Sie stattdessen den DigitalOcean-Provider und definieren eine digitalocean_droplet-Ressource, ähnlich dem folgenden Beispielschnipsel:

new Droplet(this, 'web', {
  image: 'ubuntu-20-04-x64',
  name,
  region: 'lon1',
  size: 's-1vcpu-1gb',
}

Dann können Sie das cdktf-CLI-Tool verwenden, um diesen TypeScript-Code in Terraform-kompatibles JSON zu übersetzen und es an den Provider weiterzugeben, der die entsprechenden API-Aufrufe tätigt, um den Droplet in Ihrem Namen zu erstellen.

Jetzt, da Sie verstehen, was ein Provider ist, können Sie den DigitalOcean-Provider für Ihr CDKTF-Projekt einrichten.

Öffnen Sie die Datei cdktf.json und fügen Sie den String digitalocean/digitalocean zum Array terraformProviders hinzu:

cdktf.json
{
  "language": "typescript",
  "app": "npx ts-node main.ts",
  "projectId": "28c87598-4343-47a9-bb5d-8fb0e031c41b",
  "terraformProviders": ["digitalocean/digitalocean"],
  "terraformModules": [],
  "context": {
    "excludeStackIdFromLogicalIds": "true",
    "allowSepCharsInLogicalIds": "true"
  }
}

digitalocean/digitalocean ist der Bezeichner für den DigitalOcean-Anbieter im Terraform-Register.

Speichern Sie die Datei und schließen Sie sie.

Als nächstes führen Sie cdktf get aus, um den Anbieter herunterzuladen und zu installieren.

  1. cdktf get

cdktf get wird den Anbieter herunterladen, das Schema extrahieren, die entsprechenden TypeScript-Klassen generieren und diese als TypeScript-Modul unter .gen/providers/ hinzufügen. Diese automatische Codegenerierung ermöglicht es Ihnen, beliebige Terraform-Anbieter und HCL-Module mit CDKTF zu verwenden, und ist die Methode, wie CDKTF Codevervollständigung in unterstützenden Editoren bereitstellen kann.

Nachdem cdktf get abgeschlossen ist, sehen Sie eine Ausgabe ähnlich wie folgt:

Output
Generated typescript constructs in the output directory: .gen

Sie werden auch ein neues Verzeichnis namens .gen sehen, das den generierten Code des Anbieters enthält.

In diesem Schritt haben Sie den Anbieter digitalocean/digitalocean in das Projekt installiert. Im nächsten Schritt werden Sie den DigitalOcean-Anbieter mit den erforderlichen Anmeldeinformationen konfigurieren, um den Anbieter mit der DigitalOcean-API zu authentifizieren.

Schritt 4 – Konfigurieren des DigitalOcean-Anbieters

In diesem Schritt konfigurieren Sie den DigitalOcean-Anbieter mit Ihrem DigitalOcean Personal Access Token, der es dem Anbieter ermöglicht, im Auftrag von Ihnen auf die DigitalOcean-API zuzugreifen.

Verschiedene Anbieter erfordern und unterstützen unterschiedliche Anmeldeinformationen zur Authentifizierung mit der Upstream-API. Für den DigitalOcean-Anbieter müssen Sie Ihren DigitalOcean Personal Access Token angeben. Sie können den Token dem Anbieter bereitstellen, indem Sie ihn als Umgebungsvariable DIGITALOCEAN_TOKEN oder DIGITALOCEAN_ACCESS_TOKEN setzen.

Führen Sie den folgenden Befehl in Ihrem Terminal aus, um die Umgebungsvariable für diese Terminal-Sitzung festzulegen.

  1. export DIGITALOCEAN_ACCESS_TOKEN="your_personal_access_token"

Hinweis: Durch Aufruf von export setzen Sie die Umgebungsvariable nur für diese Terminal-Sitzung. Wenn Sie das Terminal schließen und erneut öffnen oder die cdktf-Befehle in einem anderen Terminal ausführen, müssen Sie den export-Befehl erneut ausführen, damit die Umgebungsvariable wirksam wird.

Als nächstes geben Sie den Anbieter innerhalb der Klasse MyStack an, was es Ihnen ermöglicht, Ressourcen, die vom Anbieter bereitgestellt werden, in Ihrem Stapel zu definieren. Aktualisieren Sie die Datei main.ts wie folgt:

main.ts
import { Construct } from "constructs";
import { App, TerraformStack } from "cdktf";
import { DigitaloceanProvider } from "./.gen/providers/digitalocean"

class MyStack extends TerraformStack {
  constructor(scope: Construct, name: string) {
    super(scope, name);

    new DigitaloceanProvider(this, 'provider')
    
  }
}

const app = new App();
new MyStack(app, "infra");
app.synth();

Das Modul für den Anbieter befindet sich unter ./.gen/providers/digitalocean, das automatisch generiert wurde, als Sie cdktf get ausgeführt haben.

Sie haben den digitalocean/digitalocean-Anbieter in diesem Schritt mit Anmeldeinformationen konfiguriert. Als nächstes beginnen Sie mit der Definition der Infrastruktur, die Teil des Ziels dieses Tutorials ist.

Schritt 5 — Definieren von Webanwendungen auf Droplets

In diesem Schritt definieren Sie zwei NGINX-Server, die jeweils unterschiedliche Dateien bereitstellen, die auf zwei identischen Ubuntu 20.04 Droplets bereitgestellt sind.

Sie beginnen mit der Definition der beiden Droplets. Ändern Sie main.ts mit den hervorgehobenen Änderungen:

main.ts
...
import { DigitaloceanProvider, Droplet } from "./.gen/providers/digitalocean"

class MyStack extends TerraformStack {
  constructor(scope: Construct, name: string) {
    ...
    const dropletNames = ['foo', 'bar']
    const droplets = dropletNames.map(name => new Droplet(this, name, {
        image: 'ubuntu-20-04-x64',
        name,
        region: 'lon1',
        size: 's-1vcpu-1gb',
      })
    )
  }
}

Sie verwenden eine JavaScript-native Schleife (Array.prototype.map()), um die Duplizierung im Code zu vermeiden.

Genauso wie beim Erstellen des Droplets über die Konsole gibt es mehrere Parameter zu spezifizieren:

  • image – die Linux-Distribution und Version, die Ihr Droplet ausführen wird.
  • region – das Rechenzentrum, in dem der Droplet ausgeführt wird.
  • size – die Menge an CPU- und Speicherressourcen, die dem Droplet zugewiesen werden sollen.
  • name – ein eindeutiger Name, der verwendet wird, um auf das Droplet zu verweisen.

Die Werte für image, region und size müssen Dinge sein, die von DigitalOcean unterstützt werden. Sie finden die gültigen Werte (genannt slugs) für alle unterstützten Linux-Distribution-Images, Droplet-Größen und Regionen auf der Seite der DigitalOcean API Slugs. Eine vollständige Liste der erforderlichen und optionalen Attribute finden Sie auf der digitalocean_droplet-Dokumentationsseite.

Hinzufügen eines SSH-Schlüssels

Als Teil der Voraussetzungen haben Sie einen SSH-Public-Key ohne Passwort in Ihr DigitalOcean-Konto hochgeladen und dessen Namen notiert. Sie verwenden diesen Namen jetzt, um die ID des SSH-Schlüssels abzurufen und sie in die Definition Ihres Droplets einzufügen.

Da der SSH-Schlüssel manuell zu Ihrem DigitalOcean-Konto hinzugefügt wurde, handelt es sich nicht um eine Ressource, die von Ihrer aktuellen Terraform-Konfiguration verwaltet wird. Wenn Sie versuchen, eine neue digitalocean_ssh_key-Ressource zu definieren, wird ein neuer SSH-Schlüssel erstellt, anstatt den vorhandenen zu verwenden.

Stattdessen definieren Sie eine neue digitalocean_ssh_key Datenquelle. In Terraform werden Datenquellen verwendet, um Informationen über Infrastrukturen abzurufen, die nicht von der aktuellen Terraform-Konfiguration verwaltet werden. Mit anderen Worten bieten sie einen schreibgeschützten Blick auf den Zustand bereits vorhandener externer Infrastrukturen. Sobald eine Datenquelle definiert ist, können Sie die Daten an anderer Stelle in Ihrer Terraform-Konfiguration verwenden.

Weiterhin in main.ts und innerhalb des Konstruktors von MyStack definieren Sie eine neue Datenquelle DataDigitaloceanSshKey und übergeben den Namen, den Sie Ihrem SSH-Schlüssel zugewiesen haben (hier ist der Name do_cdktf):

main.ts
...
import { DataDigitaloceanSshKey, DigitaloceanProvider, Droplet } from "./.gen/providers/digitalocean"

class MyStack extends TerraformStack {
  constructor(scope: Construct, name: string) {
    ...
    const dropletNames = ['foo', 'bar']
    const sshKey = new DataDigitaloceanSshKey(this, 'sshKey', {
      name: 'do_cdktf',
    })
    const droplets = dropletNames.map(name => new Droplet(this, name, {
    ...
  }
}
...

Dann aktualisieren Sie die Definition des Droplets, um den SSH-Schlüssel einzuschließen:

main.ts
...
const droplets = dropletNames.map(name => new Droplet(this, name, {
  image: 'ubuntu-20-04-x64',
  name,
  region: 'lon1',
  size: 's-1vcpu-1gb',
  sshKeys: [sshKey.id.toString()]
}))
...

Nach der Bereitstellung können Sie auf das Droplet mit einem privaten SSH-Schlüssel anstatt eines Passworts zugreifen.

Spezifizieren des Benutzerdatenskripts zur Installation von NGINX

Sie haben nun zwei identische Droplets definiert, die Ubuntu ausführen und für SSH-Zugriff konfiguriert sind. Die nächste Aufgabe besteht darin, NGINX auf jedem Droplet zu installieren.

Bei der Erstellung eines Droplets wird ein Werkzeug namens CloudInit den Server initialisieren. CloudInit kann eine Datei namens Benutzerdaten akzeptieren, die beeinflussen können, wie der Server initialisiert wird. Die Benutzerdaten können beliebige cloud-config-Dateien oder Skripte sein, die vom Server interpretiert werden können, wie z.B. Bash-Skripte.

In den restlichen Schritten werden Sie ein Bash-Skript erstellen und es als Benutzerdaten des Droplets angeben. Das Skript wird NGINX als Teil des Initialisierungsprozesses installieren. Außerdem wird das Skript auch den Inhalt der Datei /var/www/html/index.html (die Standarddatei, die von NGINX bereitgestellt wird) mit dem Hostnamen und der IP-Adresse des Droplets ersetzen, was dazu führt, dass die beiden NGINX-Server unterschiedliche Dateien bereitstellen. Im nächsten Schritt werden Sie beide dieser NGINX-Server hinter einen Lastenausgleicher stellen; durch das Bereitstellen unterschiedlicher Dateien wird deutlich, ob der Lastenausgleicher Anfragen korrekt verteilt oder nicht.

Weiterhin in main.ts fügen Sie ein neues userData-Eigenschaft zum Konfigurationsobjekt des Droplets hinzu:

main.ts
...
class MyStack extends TerraformStack {
  constructor(scope: Construct, name: string) {
    ...
    const droplets = dropletNames.map(name => new Droplet(this, name, {
      image: 'ubuntu-20-04-x64',
      name,
      region: 'lon1',
      size: 's-1vcpu-1gb',
      sshKeys: [sshKey.id.toString()],
      userData: `#!/bin/bash

apt-get -y update
apt-get -y install nginx
export HOSTNAME=$(curl -s http://169.254.169.254/metadata/v1/hostname)
export PUBLIC_IPV4=$(curl -s http://169.254.169.254/metadata/v1/interfaces/public/0/ipv4/address)
echo Droplet: $HOSTNAME, IP Address: $PUBLIC_IPV4 > /var/www/html/index.html
`
    }))
  }
}

Warnung: Stellen Sie sicher, dass keine Leerzeilen vor dem Shebang (#!) stehen; sonst wird das Skript möglicherweise nicht ausgeführt.

Wenn der Droplet zum ersten Mal bereitgestellt wird, wird das Skript als Benutzer root ausgeführt. Es wird den Paketmanager von Ubuntu, APT, verwenden, um das Paket nginx zu installieren. Anschließend wird es den Metadatendienst von DigitalOcean nutzen, um Informationen über sich selbst abzurufen, und den Hostnamen sowie die IP-Adresse in die Datei index.html schreiben, die von NGINX bereitgestellt wird.

In diesem Schritt haben Sie die beiden Droplets definiert, die Ubuntu ausführen, jeden mit SSH-Zugriff konfiguriert und NGINX mithilfe der Funktion für Benutzerdaten installiert. Im nächsten Schritt werden Sie einen Lastenausgleicher definieren, der vor diesen NGINX-Servern sitzt, und ihn so konfigurieren, dass er die Last gleichmäßig verteilt.

Schritt 6 — Definieren eines Lastenausgleichers

In diesem Schritt werden Sie einen DigitalOcean-Lastenausgleicher definieren, indem Sie eine Instanz der Ressource digitalocean_loadbalancer definieren.

Fügen Sie immer noch in main.ts folgende Definition für einen Lastenausgleicher am Ende des Konstruktors von MyStack hinzu:

main.ts
...
import { App, Fn, TerraformStack } from "cdktf";
import { DataDigitaloceanSshKey, DigitaloceanProvider, Droplet, Loadbalancer } from "./.gen/providers/digitalocean"

class MyStack extends TerraformStack {
  constructor(scope: Construct, name: string) {
    ...
    new Loadbalancer(this, 'lb', {
      name: 'default',
      region: 'lon1',
      algorithm: 'round_robin',
      forwardingRule: [{
        entryProtocol: 'http',
        entryPort: 80,
        targetProtocol: 'http',
        targetPort: 80,
      }],
      dropletIds: droplets.map((droplet) => Fn.tonumber(droplet.id))
    })
  }
}
...

Das Argument forwardingRule gibt dem Lastenausgleicher an, HTTP-Anfragen auf Port 80 anzuhören und sie an jeden der Droplets auf Port 80 weiterzuleiten.

Die dropletIds geben an, an welche Droplets der Lastenausgleicher Anfragen weiterleiten soll. Es nimmt eine Zahl, aber der Wert von droplet.id ist eine Zeichenfolge. Daher haben Sie die Fn.tonumber Terraform-Funktion verwendet, um den Zeichenfolgen-Droplet-ID-Wert in eine Zahl umzuwandeln.

Hinweis: Sie haben hier die Terraform-Funktion Fn.tonumber anstelle von JavaScript-eigenem parseInt verwendet, weil der Wert von droplet.id unbekannt ist, bis das Droplet bereitgestellt ist. Terraform-Funktionen sind darauf ausgelegt, auf unbekannte Laufzeitwerte zu wirken, bevor Terraform eine Konfiguration anwendet.

Speichern und schließen Sie die Datei.

Sie haben nun zwei Droplets und einen Lastenausgleicher definiert, der vor ihnen liegt. Ihr main.ts sollte ähnlich wie folgt aussehen:

main.ts
import { Construct } from "constructs";
import { App, Fn, TerraformStack } from "cdktf";
import { DataDigitaloceanSshKey, DigitaloceanProvider, Droplet, Loadbalancer } from "./.gen/providers/digitalocean"

class MyStack extends TerraformStack {
  constructor(scope: Construct, name: string) {
    super(scope, name);

    new DigitaloceanProvider(this, 'provider')

    const dropletNames = ['foo', 'bar']
    const sshKey = new DataDigitaloceanSshKey(this, 'sshKey', {
      name: 'do_cdktf',
    })
    const droplets = dropletNames.map(name => new Droplet(this, name, {
        image: 'ubuntu-20-04-x64',
        name,
        region: 'lon1',
        size: 's-1vcpu-1gb',
        sshKeys: [sshKey.id.toString()],
        userData: `#!/bin/bash

apt-get -y update
apt-get -y install nginx
export HOSTNAME=$(curl -s http://169.254.169.254/metadata/v1/hostname)
export PUBLIC_IPV4=$(curl -s http://169.254.169.254/metadata/v1/interfaces/public/0/ipv4/address)
echo Droplet: $HOSTNAME, IP Address: $PUBLIC_IPV4 > /var/www/html/index.html
`
      })
    )

    new Loadbalancer(this, 'lb', {
      name: 'default',
      region: 'lon1',
      algorithm: 'round_robin',
      forwardingRule: [{
        entryProtocol: 'http',
        entryPort: 80,
        targetProtocol: 'http',
        targetPort: 80,
      }],
      dropletIds: droplets.map((droplet) => Fn.tonumber(droplet.id))
    })
  }
}

const app = new App();
new MyStack(app, "infra");
app.synth();

Im nächsten Schritt werden Sie das cdktf-CLI-Tool verwenden, um Ihr gesamtes CDKTF-Projekt zu aktualisieren.

Schritt 7 — Bereitstellung Ihrer Infrastruktur

In diesem Schritt verwenden Sie das cdktf-CLI-Tool, um die Droplets und Load Balancer bereitzustellen, die Sie in den vorherigen Schritten definiert haben.

Stellen Sie sicher, dass Sie sich im Verzeichnis infra/ befinden und die Umgebungsvariable DIGITALOCEAN_ACCESS_TOKEN für Ihre Terminalsession festgelegt haben. Führen Sie dann den Befehl cdktf deploy aus:

  1. cdktf deploy

Sie sollten eine Ausgabe ähnlich der folgenden sehen:

Output
infra Initializing the backend... infra Initializing provider plugins... infra - Reusing previous version of digitalocean/digitalocean from the dependency lock file infra - Using previously-installed digitalocean/digitalocean v2.19.0 infra Terraform has been successfully initialized! infra 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: infra # digitalocean_droplet.bar (bar) will be created + resource "digitalocean_droplet" "bar" { + backups = false + created_at = (known after apply) + disk = (known after apply) + graceful_shutdown = false + 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 = "bar" + price_hourly = (known after apply) + price_monthly = (known after apply) + private_networking = (known after apply) + region = "lon1" + resize_disk = true + size = "s-1vcpu-1gb" + ssh_keys = [ + "34377800", ] + status = (known after apply) + urn = (known after apply) + user_data = "f9b1d9796d069fe504ce0d89439b6b664b14b1a1" + vcpus = (known after apply) + volume_ids = (known after apply) + vpc_uuid = (known after apply) } # digitalocean_droplet.foo (foo) wird erstellt + resource "digitalocean_droplet" "foo" { + backups = false + created_at = (known after apply) + disk = (known after apply) + graceful_shutdown = false + 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 = "foo" + price_hourly = (known after apply) + price_monthly = (known after apply) + private_networking = (known after apply) + region = "lon1" + resize_disk = true + size = "s-1vcpu-1gb" + ssh_keys = [ + "34377800", ] + status = (known after apply) + urn = (known after apply) + user_data = "f9b1d9796d069fe504ce0d89439b6b664b14b1a1" + vcpus = (known after apply) + volume_ids = (known after apply) + vpc_uuid = (known after apply) } # digitalocean_loadbalancer.lb (lb) wird erstellt + resource "digitalocean_loadbalancer" "lb" { + algorithm = "round_robin" + disable_lets_encrypt_dns_records = false + droplet_ids = (known after apply) + enable_backend_keepalive = false + enable_proxy_protocol = false + id = (known after apply) + ip = (known after apply) + name = "default" + redirect_http_to_https = false + region = "lon1" + size_unit = (known after apply) + status = (known after apply) + urn = (known after apply) + vpc_uuid = (known after apply) + forwarding_rule { + certificate_id = (known after apply) + certificate_name = (known after apply) + entry_port = 80 + entry_protocol = "http" + target_port = 80 + target_protocol = "http" + tls_passthrough = false } + healthcheck { + check_interval_seconds = (known after apply) + healthy_threshold = (known after apply) + path = (known after apply) + port = (known after apply) + protocol = (known after apply) + response_timeout_seconds = (known after apply) + unhealthy_threshold = (known after apply) } + sticky_sessions { + cookie_name = (known after apply) + cookie_ttl_seconds = (known after apply) + type = (known after apply) } } Plan: 3 to add, 0 to change, 0 to destroy. ───────────────────────────────────────────────────────────────────────────── Saved the plan to: plan To perform exactly these actions, run the following command to apply: terraform apply "plan" Please review the diff output above for infra ❯ Approve Applies the changes outlined in the plan. Dismiss Stop

Hinweis: CDKTF wird weiterentwickelt, und die Ausgabe kann von der oben gezeigten abweichen.

Diese Anzeige listet alle Ressourcen und Eigenschaften auf, die cdktf plant zu erstellen, zu aktualisieren und zu zerstören. Einige Werte, wie die ID eines Droplets, sind erst bekannt, nachdem die Ressource bereitgestellt wurde. Für diese sehen Sie (known after apply) als den Eigenschaftswert in der Ausgabe.

Überprüfen Sie die Liste der Ressourcen, um sicherzustellen, dass sie Ihren Erwartungen entspricht. Verwenden Sie dann die Pfeiltasten, um die Option Genehmigen auszuwählen, und drücken Sie ENTER.

Sie werden eine Ausgabe ähnlich der folgenden sehen:

Output
infra digitalocean_droplet.foo (foo): Creating... digitalocean_droplet.bar (bar): Creating... infra digitalocean_droplet.bar (bar): Still creating... [10s elapsed] infra digitalocean_droplet.foo (foo): Still creating... [10s elapsed] 1 Stack deploying 0 Stacks done 0 Stacks waiting

Diese Ausgabe informiert Sie darüber, dass cdktf mit der DigitalOcean API kommuniziert, um das Droplet zu erstellen. cdktf erstellt zuerst die Droplets, da der Load Balancer von der ID des Droplets abhängt, die erst nach der Bereitstellung der Droplets bekannt ist.

Die Erstellung des Droplets dauert in der Regel weniger als eine Minute. Sobald die Droplets bereitgestellt sind, fährt cdktf mit der Erstellung des Load Balancers fort.

Output
infra digitalocean_droplet.bar (bar): Creation complete after 54s [id=298041598] infra digitalocean_droplet.foo (foo): Creation complete after 55s [id=298041600] infra digitalocean_loadbalancer.lb (lb): Creating... infra digitalocean_loadbalancer.lb (lb): Still creating... [10s elapsed]

Der Lastenausgleich kann länger dauern. Nachdem der Lastenausgleich erstellt wurde, sehen Sie eine Zusammenfassung, die anzeigt, dass der Stapel erfolgreich bereitgestellt wurde.

Output
infra digitalocean_loadbalancer.lb (lb): Still creating... [1m30s elapsed] infra digitalocean_loadbalancer.lb (lb): Creation complete after 1m32s [id=4f9ae2b7-b649-4fb4-beed-96b95bb72dd1] infra Apply complete! Resources: 3 added, 0 changed, 0 destroyed. No outputs found.

Sie können nun die DigitalOcean-Konsole besuchen, wo Sie einen Lastenausgleich mit dem Namen default und zwei gesunde Droplets mit den Namen foo und bar sehen können, von denen jedes als Ziel für den Lastenausgleich dient.

Sie können testen, ob NGINX ausgeführt wird und Inhalte korrekt bereitgestellt werden, indem Sie die IP-Adresse jedes Droplets besuchen. Sie sollten einen Text ähnlich wie den folgenden sehen:

Droplet: bar, IP Address: droplet_ip

Wenn Sie diesen Text nicht sehen oder der Server nicht antwortet, überprüfen Sie, ob die von Ihnen angegebenen Benutzerdaten korrekt sind und ob keine Zeichen (einschließlich Zeilenumbrüche) dem Shebang (#!) vorausgehen. Sie können sich auch über SSH mit dem Droplet verbinden, indem Sie Ihren SSH-Privatschlüssel verwenden und die von CloudInit generierten Ausgabeprotokolle unter /var/log/cloud-init-output.log überprüfen:

  1. ssh -i path_to_ssh_private_key root@droplet_ip

Nachdem Sie bestätigt haben, dass die Droplets aktiv sind und Inhalte bereitstellen, können Sie mit dem Testen des Lastenausgleichs beginnen. Sie tun dies, indem Sie einige Anfragen senden.

Führen Sie den folgenden Befehl von Ihrem Terminal aus, um zehn Anfragen an den Lastenausgleich zu senden:

  1. for run in {1..10}; do curl http://load_balancer_ip/; done

Sie sollten eine Ausgabe ähnlich der folgenden sehen, wobei die angezeigten IP-Adressen jedoch unterschiedlich sein werden:

Output
Droplet: foo, IP Address: droplet_foo_ip Droplet: bar, IP Address: droplet_bar_ip Droplet: foo, IP Address: droplet_foo_ip Droplet: bar, IP Address: droplet_bar_ip Droplet: bar, IP Address: droplet_bar_ip Droplet: foo, IP Address: droplet_foo_ip Droplet: bar, IP Address: droplet_bar_ip Droplet: foo, IP Address: droplet_foo_ip Droplet: bar, IP Address: droplet_bar_ip Droplet: foo, IP Address: droplet_foo_ip

Es zeigt, dass Anfragen an den Lastenausgleich fünfmal an jedes Droplet weitergeleitet wurden, was darauf hinweist, dass der Lastenausgleich funktioniert.

Hinweis: Der Lastenausgleich gleicht möglicherweise nicht immer perfekt zwischen den beiden Droplets aus; Sie könnten feststellen, dass vier Anfragen an ein Droplet gesendet wurden und sechs an das andere. Dieses Verhalten ist normal.

In diesem Schritt haben Sie cdktf verwendet, um Ihre Ressourcen bereitzustellen, und dann die IP-Adressen Ihrer Droplets und Lastenausgleicher in der DigitalOcean-Konsole ermittelt. Anschließend haben Sie Anfragen an jedes Droplet und den Lastenausgleicher gesendet, um zu bestätigen, dass sie funktionieren.

Im nächsten Schritt werden Sie die IP-Adressen der Droplets und des Lastenausgleichers ohne Anmeldung in die DigitalOcean-Konsole abrufen.

Schritt 8 — Ausgabe von Informationen

In dem vorherigen Schritt mussten Sie sich in die DigitalOcean-Konsole einloggen, um die IP-Adressen Ihres Droplets und des Lastenausgleichers zu erhalten. In diesem Schritt werden Sie Ihren Code geringfügig ändern, damit diese Informationen im Ausgabebereich des Befehls cdktf deploy gedruckt werden, was Ihnen einen Besuch in der Konsole erspart.

Terraform speichert die Konfiguration und den Status seiner verwalteten Ressourcen in Zustandsdateien. Für Ihren Stapel infra befindet sich die Zustandsdatei unter infra/terraform.infra.tfstate. Sie werden die IP-Adressen der Droplets und des Lastenausgleichers in dieser Zustandsdatei finden.

Das Durchsuchen einer großen Datei kann jedoch umständlich sein. CDKTF bietet das TerraformOutput-Konstrukt, das Sie verwenden können, um Variablen auszugeben und außerhalb des Stapels verfügbar zu machen. Alle Ausgaben werden nach dem Ausführen von cdktf deploy im stdout gedruckt. Das Ausführen von cdktf output kann Ausgaben auch jederzeit drucken.

Hinweis: Obwohl Sie in diesem Tutorial nur Ausgaben verwenden, um Informationen in die Konsole zu drucken, kommt seine eigentliche Stärke von Stapeln, die Ausgaben anderer Stapel als Eingabe verwenden, eine Funktion, die als Querverweise zwischen Stapeln bekannt ist.

Aktualisieren Sie die Datei main.ts, um die Ausgaben der IP-Adressen des Lastenausgleichs und der Droplets einzuschließen:

main.ts
import { Construct } from "constructs";
import { App, Fn, TerraformOutput, TerraformStack } from "cdktf";
import { DataDigitaloceanSshKey, DigitaloceanProvider, Droplet, Loadbalancer } from "./.gen/providers/digitalocean"

class MyStack extends TerraformStack {
  constructor(scope: Construct, name: string) {
    ...
    const lb = new Loadbalancer(this, 'lb', {
      ...
    })

    new TerraformOutput(this, "loadBalancerIP", {
      value: lb.ip,
    });

    droplets.forEach((droplet, index) => new TerraformOutput(this, `droplet${index}IP`, {
      value: droplet.ipv4Address
    }))
  }
}
...

Speichern und schließen Sie die Datei.

Führen Sie cdktf deploy aus, um die Änderung zu aktualisieren:

  1. cdktf deploy

In der Ausgabe sollten Sie etwas Ähnliches wie das Folgende sehen:

Output
───────────────────────────────────────────────────────────────────────────── Changes to Outputs: + droplet0IP = "droplet_foo_ip" + droplet1IP = "droplet_bar_ip" + loadBalancerIP = "load_balancer_ip" You can apply this plan to save these new output values to the Terraform state, without changing any real infrastructure. ─────────────────────────────────────────────────────────────────────────────

Diese Ausgabe informiert Sie darüber, dass keine Infrastrukturänderungen vorgenommen werden, sondern nur das, was vom Stapel ausgegeben wird.

Verwenden Sie die Pfeiltasten, um Akzeptieren auszuwählen, und drücken Sie dann ENTER. Am Ende der Terminalausgabe sollten Sie etwas Ähnliches wie folgt sehen:

Output
infra droplet0IP = droplet_foo_ip droplet1IP = droplet_bar_ip loadBalancerIP = load_balancer_ip

Jetzt werden jedes Mal, wenn Sie cdktf deploy oder cdktf output ausführen, die IP-Adressen der Droplets und der Lastenausgleicher im Terminal ausgegeben, was den Zugriff auf diese Informationen über die DigitalOcean-Konsole überflüssig macht.

Sie haben nun zwei Droplets und einen Lastenausgleicher bereitgestellt und bestätigt, dass sie funktionieren. Sie können das von Ihnen entwickelte CDKTF-Projekt als Basis verwenden, um komplexere Infrastrukturen zu definieren (eine Referenzimplementierung finden Sie unter do-community / digitalocean-cdktf-typescript).

Die Ressourcen, die in diesem Tutorial bereitgestellt werden, verursachen Kosten. Wenn Sie nicht beabsichtigen, die erstellte Infrastruktur zu verwenden, sollten Sie sie zerstören. Im nächsten und letzten Schritt werden Sie das Projekt aufräumen, indem Sie die im Tutorial erstellten Ressourcen zerstören.

Schritt 9 — Zerstören Ihrer Infrastruktur

In diesem Schritt werden alle im Tutorial erstellten Ressourcen entfernt.

Weiterhin im Verzeichnis infra/, führen Sie cdktf destroy aus:

  1. cdktf destroy

Sie sollten eine Ausgabe ähnlich der folgenden sehen:

Output
infra Initializing the backend... infra Initializing provider plugins... infra - Reusing previous version of digitalocean/digitalocean from the dependency lock file infra - Using previously-installed digitalocean/digitalocean v2.19.0 infra Terraform has been successfully initialized! infra digitalocean_droplet.bar (bar): Refreshing state... [id=298041598] digitalocean_droplet.foo (foo): Refreshing state... [id=298041600] infra digitalocean_loadbalancer.lb (lb): Refreshing state... [id=4f9ae2b7-b649-4fb4-beed-96b95bb72dd1] infra Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols: - destroy Terraform will perform the following actions: infra # digitalocean_droplet.bar (bar) will be destroyed - resource "digitalocean_droplet" "bar" { - backups = false -> null - created_at = "2022-05-02T10:04:16Z" -> null - disk = 25 -> null - graceful_shutdown = false -> null - id = "298041598" -> null - image = "ubuntu-20-04-x64" -> null - ipv4_address = "droplet_bar_public_ip" -> null - ipv4_address_private = "droplet_bar_private_ip" -> null - ipv6 = false -> null - locked = false -> null - memory = 1024 -> null - monitoring = false -> null - name = "bar" -> null - price_hourly = 0.00744 -> null - price_monthly = 5 -> null - private_networking = true -> null - region = "lon1" -> null - resize_disk = true -> null - size = "s-1vcpu-1gb" -> null - ssh_keys = [ - "34377800", ] -> null - status = "active" -> null - tags = [] -> null - urn = "do:droplet:298041598" -> null - user_data = "f9b1d9796d069fe504ce0d89439b6b664b14b1a1" -> null - vcpus = 1 -> null - volume_ids = [] -> null - vpc_uuid = "bed80b32-dc82-11e8-83ec-3cfdfea9f3f0" -> null } # digitalocean_droplet.foo (foo) wird zerstört - resource "digitalocean_droplet" "foo" { - backups = false -> null - created_at = "2022-05-02T10:04:16Z" -> null - disk = 25 -> null - graceful_shutdown = false -> null - id = "298041600" -> null - image = "ubuntu-20-04-x64" -> null - ipv4_address = "droplet_foo_public_ip" -> null - ipv4_address_private = "droplet_foo_private_ip" -> null - ipv6 = false -> null - locked = false -> null - memory = 1024 -> null - monitoring = false -> null - name = "foo" -> null - price_hourly = 0.00744 -> null - price_monthly = 5 -> null - private_networking = true -> null - region = "lon1" -> null - resize_disk = true -> null - size = "s-1vcpu-1gb" -> null - ssh_keys = [ - "34377800", ] -> null - status = "active" -> null - tags = [] -> null - urn = "do:droplet:298041600" -> null - user_data = "f9b1d9796d069fe504ce0d89439b6b664b14b1a1" -> null - vcpus = 1 -> null - volume_ids = [] -> null - vpc_uuid = "bed80b32-dc82-11e8-83ec-3cfdfea9f3f0" -> null } # digitalocean_loadbalancer.lb (lb) wird zerstört - resource "digitalocean_loadbalancer" "lb" { - algorithm = "round_robin" -> null - disable_lets_encrypt_dns_records = false -> null - droplet_ids = [ - 298041598, - 298041600, ] -> null - enable_backend_keepalive = false -> null - enable_proxy_protocol = false -> null - id = "4f9ae2b7-b649-4fb4-beed-96b95bb72dd1" -> null - ip = "load_balancer_ip" -> null - name = "default" -> null - redirect_http_to_https = false -> null - region = "lon1" -> null - size_unit = 1 -> null - status = "active" -> null - urn = "do:loadbalancer:4f9ae2b7-b649-4fb4-beed-96b95bb72dd1" -> null - vpc_uuid = "bed80b32-dc82-11e8-83ec-3cfdfea9f3f0" -> null - forwarding_rule { - entry_port = 80 -> null - entry_protocol = "http" -> nul infra l - target_port = 80 -> null - target_protocol = "http" -> null - tls_passthrough = false -> null } - healthcheck { - check_interval_seconds = 10 -> null - healthy_threshold = 5 -> null - path = "/" -> null - port = 80 -> null - protocol = "http" -> null - response_timeout_seconds = 5 -> null - unhealthy_threshold = 3 -> null } - sticky_sessions { - cookie_ttl_seconds = 0 -> null - type = "none" -> null } } Plan: 0 to add, 0 to change, 3 to destroy. ───────────────────────────────────────────────────────────────────────────── Saved the plan to: plan To perform exactly these actions, run the following command to apply: terraform apply "plan" Please review the diff output above for infra ❯ Approve Applies the changes outlined in the plan. Dismiss Stop

Dieses Mal zeigt es anstelle von + neben jeder Ressource - an, was darauf hinweist, dass CDKTF plant, die Ressource zu zerstören. Überprüfen Sie die vorgeschlagenen Änderungen und verwenden Sie dann die Pfeiltasten, um Genehmigen auszuwählen, und drücken Sie ENTER. Der DigitalOcean-Anbieter wird nun mit der DigitalOcean-API kommunizieren, um die Ressourcen zu zerstören.

Output
infra digitalocean_loadbalancer.lb (lb): Destroying... [id=4f9ae2b7-b649-4fb4-beed-96b95bb72dd1] infra digitalocean_loadbalancer.lb (lb): Destruction complete after 1s infra digitalocean_droplet.bar (bar): Destroying... [id=298041598] digitalocean_droplet.foo (foo): Destroying... [id=298041600]

Der Lastenausgleich wurde zuerst gelöscht, da er keine Abhängigkeiten hat (keine anderen Ressourcen verweisen auf den Lastenausgleich in ihren Eingaben). Da der Lastenausgleich auf die Droplets verweist, können sie erst zerstört werden, nachdem der Lastenausgleich zerstört wurde.

Nachdem die Ressourcen zerstört wurden, wird die folgende Zeile in der Ausgabe gedruckt:

Output
Destroy complete! Resources: 3 destroyed.

Zusammenfassung

In diesem Tutorial haben Sie CDKTF verwendet, um eine Lastenausgleichswebseite bereitzustellen und zu zerstören, die aus zwei DigitalOcean-Droplets besteht, auf denen NGINX-Server ausgeführt werden, die hinter einem Lastenausgleicher bereitgestellt werden. Sie haben auch Informationen über die Ressourcen auf dem Terminal ausgegeben.

CDKTF ist eine Abstraktionsschicht über Terraform. Ein gutes Verständnis von Terraform ist hilfreich, um CDKTF zu verstehen. Wenn Sie mehr über Terraform erfahren möchten, können Sie die Serie „Wie man Infrastruktur mit Terraform verwaltet“ lesen, die Terraform ausführlich behandelt.

Sie können auch die offizielle CDK for Terraform-Dokumentation und Tutorials besuchen, um mehr über CDKTF zu erfahren.

Source:
https://www.digitalocean.com/community/tutorials/how-to-deploy-load-balanced-web-applications-on-digitalocean-with-cdk-for-terraform-and-typescript