So konfigurieren Sie Ihre Fastly Services mit Terraform

This post was written with version 0.30.0 of the Fastly Terraform provider. This is no longer the latest release so please refer to the documentation.

Während sich Ihre Fastly Services selbstverständlich auch sporadisch über das Web-Interface, die CLI oder die API konfigurieren lassen, ist es oft sinnvoller, Ihre Konfiguration parallel zur Entwicklung Ihres Anwendungscodes aufzuzeichnen. Edge-Logik auf dieselbe Weise wie Konfigurationsänderungen für Anwendungen und Infrastruktur bereitzustellen ist mittlerweile fast unabdingbar, vor allem, wenn Sie viel auf der Edge programmieren. Da die Grenzen zwischen Infrastruktur und Software bei Cloud-Services nicht genau definierbar sind, benötigen Sie zunehmend eine Möglichkeit, Ihren Code und Ihre Konfigurationsänderungen für die Services mehrerer Anbieter in einem einzigen versionierten Deployment bereitzustellen. Bei Fastly nennen wir dieses Prinzip Infrastructure as Code (IaC).

Wir haben Ihnen in einem früheren Blogpost bereits erläutert, wie Sie mit dem beliebten Tool Terraform eine Continuous Deployment Pipeline aufbauen können, und haben die verfügbaren Funktionen iterativ verbessert, um auch unsere versionslosen Ressourcen, unsere WAF, Logging Endpoints von Drittanbietern, TLS und Compute@Edge einzubeziehen. Heute gehen wir einen Schritt zurück und werfen einen ganzheitlichen Blick darauf, wie man Fastly Services mit Terraform konfiguriert, verwaltet und bereitstellt. Ich zeige Ihnen, wie Sie dabei am besten vorgehen.

Wir beginnen mit der Erstellung eines einfachen VCL-Service mit Terraform, der zunächst als transparenter Proxy vor https://httpbin.org, der beliebten Website zum Testen von Anfragen und Antworten, dient. (Der Service nimmt also zunächst keine Änderungen am Anfrageobjekt vor, bevor es an httpbin weitergeleitet wird.) Anschließend nehmen wir einige Änderungen vor, um Ihnen zu zeigen, wie Sie Programmlogik auf der Edge ausführen können.

Wir gehen auf folgende Schritte ein:

  • Registrierung: Erstellen eines Fastly Accounts und Generieren eines API Keys

  • Programmierung: Festlegen Ihrer Anforderungen mithilfe von Terraform Code

  • Ausführung: „Planen“ und „Ausführen” Ihrer Anforderungen mithilfe der CLI von Terraform

  • Validierung: Überprüfen, ob der Service im Webbrowser korrekt läuft

  • Modifizierung: Vornehmen von Änderungen an festgelegten Ressourcen; Erstellen und Anwenden eines neuen Plans

Das folgende Diagramm hilft Ihnen, diese Schritte besser zu visualisieren und ein gedankliches Modell des gesamten Setups zu erstellen:

Configuring Fastly services with Terraform de

Erstellen Sie einen Fastly Account

Der erste Schritt besteht in der Registrierung für einen Fastly Account. Sie gehen dabei keinerlei Verpflichtungen ein und können Traffic im Wert von bis zu $ 50 kostenlos testen. Sobald Sie sich registriert und angemeldet haben, erstellen Sie ein Fastly API-Token. Dabei handelt es sich um eine eindeutige Identifizierung, die Ihnen als individuellem Nutzer zugeordnet ist. Unser Terraform Provider benötigt dieses Token, um in Ihrem Namen mit der Fastly API zu interagieren. 

Schreiben Sie Ihre Terraform Konfiguration

Als Nächstes erstellen Sie eine neue Terraform Datei mit dem Namen main.tf in Ihrem bevorzugten Code-Editor und fügen den folgenden Code hinzu:

terraform {
  required_providers {
    fastly = {
      source  = "fastly/fastly"
      version = "~> 0.30"
    }
  }
}
resource "fastly_service_v1" "test_service" { 
 name = "An Example Service"
  domain {
    name = "<name>.global.ssl.fastly.net"
  }
  backend {
    address = "httpbin.org"
    name    = "My Test Backend"
  }
  force_destroy = true
}
output "active" {
  value = fastly_service_v1.test_service.active_version
}

Damit Sie so schnell wie möglich loslegen können, beginnen Sie zunächst mit einer einzigen Datei. Wenn der Umfang Ihres Projekts später zunimmt, können Sie Ihren Code auch auf separate Dateien aufteilen, um sich die Verwaltung zu erleichtern.

Beim obigen Code handelt es sich um HCL (HashiCorp Configuration Language), mit dem Sie durch name { ... } verschiedene Blöcke und Container definieren können, um Ihre Inhalte zu strukturieren. Unser Code-Beispiel zeigt drei übergeordnete Blöcke:

1. terraform
2. resource
3. output

Der terraform Block definiert, welche Terraform Provider verwendet werden sollen. In diesem Fall interessieren wir uns für den Fastly Terraform Provider

HINWEIS: Weitere Informationen zur Verwendung von Versionsbeschränkungen finden Sie in der Terraform Dokumentation.

Ein Ressourcenblock beschreibt ein oder mehrere Infrastrukturobjekte. In der obigen Konfiguration wird eine fastly_service_v1-Ressource (als „test_service“ bezeichnet) definiert. Dabei handelt es sich um einen bestimmten Ressourcentyp, der von unserem Terraform Provider bereitgestellt wird und erforderlich ist, um einen neuen VCL-Service erstellen zu können. Diese Ressource enthält zwei Blocks – domain und backend –, die benötigt werden, um festzulegen, für welchen Domainnamen der VCL-Service Anfragen handeln und welcher Backend-Service diese Anfragen letztendlich bearbeiten soll. Unabhängig davon, ob Sie Terraform verwenden oder nicht, sind für jeden Fastly Service mindestens diese beiden Konfigurationen notwendig.

Geben Sie für <name> im Abschnitt „domain“ dieses Beispiels einen für Sie einzigartigen Wert ein. Andernfalls wird Ihnen möglicherweise eine Fehlermeldung angezeigt, weil die Domain bereits von einem anderen Service genutzt wird.

Der Block output legt Ihre Kommunikationspräferenzen fest, sobald Terraform die Infrastruktur wie gewünscht bereitgestellt hat. Diese ändern sich häufig infolge einer Bereitstellung (zum Beispiel aufgrund der Versionsnummer).

Die Ressource fastly_service_v1 generiert ein active_version-Attribut, und der Wert ist nur bekannt, wenn der Service erfolgreich erstellt und aktiviert wurde. Der Terraform Code enthält einen Ausgabeblock mit der Bezeichnung active, dessen zugewiesener Wert ein programmatischer HCL-Ausdruck ist, mit dem wir auf die aktive Version zugreifen können.

Die Syntax für die Referenzierung von Attributwerten innerhalb einer Ressource lautet: 

<resource_type>.<resource_label>.<resource_attribute>

Alle Attribute für eine bestimmte Fastly Ressource finden Sie in der entsprechenden Dokumentation für den Fastly Terraform Provider.

Führen Sie Terraform aus, um einen Plan zu erstellen

Installieren Sie Terraform CLI, sobald Sie Ihre Terraform Konfiguration erstellt haben. Nach der Installation können Sie alle verfügbaren Befehle anzeigen, indem Sie folgenden Code in Ihrem Terminal ausführen:

$ terraform -help

Zu den verfügbaren Befehlen gehört zum Beispiel auch init, der ein Terraform Projekt im aktuellen Arbeitsverzeichnis initialisiert. Führen Sie also im selben Verzeichnis, in dem Sie die Datei main.tf erstellt haben, Folgendes aus:

$ terraform init

Im Initialisierungsschritt wird Terraform aufgefordert, alle Provider herunterzuladen, die Sie im Block required_providers angegeben haben. Wenn Sie später einen anderen Provider hinzufügen müssen, aktualisieren Sie main.tf, um auf den neuen Provider zu verweisen, und führen Sie terraform init erneut aus.

Terraform nutzt Ihre main.tf-Konfiguration, um einen „Ausführungsplan“ zu erzeugen, in dem die verschiedenen Vorgänge beschrieben werden, die notwendig sind, um den gewünschten Zustand zu erreichen. Anschließend führt Terraform diesen Plan aus, um die beschriebene Infrastruktur bereitzustellen. An dieser Stelle müssen Sie Terraform auch das Fastly API-Token zur Verfügung stellen, das Sie zuvor erzeugt haben, damit Terraform in Ihrem Auftrag mit der Fastly API interagieren kann. Exportieren Sie das API-Token in Ihrer Shell als Umgebungsvariable und generieren Sie dann einen Ausführungsplan, um zu sehen, was Terraform für Sie tun möchte:

$ export FASTLY_API_KEY="====PUT YOUR TOKEN HERE===="
$ terraform plan

Terraform weiß, dass es diese Konfiguration noch nicht an einen Fastly Service übergeben hat. Der Output sollte dies widerspiegeln, indem er auf die Notwendigkeit hinweist, die verschiedenen Ressourcen zu erstellen:

An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
  + create
Terraform will perform the following actions:
 # fastly_service_v1.test_service will be created
  + resource "fastly_service_v1" "test_service" {
      + activate       = true
      + active_version = (known after apply)
      + cloned_version = (known after apply)
      + comment        = "Managed by Terraform"
      + default_host   = (known after apply)
      + default_ttl    = 3600
      + force_destroy  = true
      + id           = (known after apply)
      + name           = "An Example Service"
     + backend { 
          + address   = "httpbin.org"
          + auto_loadbalance       = true
          + between_bytes_timeout = 10000
          + connect_timeout     = 1000
          + error_threshold     = 0
          + first_byte_timeout  = 15000
          + max_conn            = 200
          + name                  = "My Test Backend"
          + port            = 80
          + ssl_check_cert        = true
          + use_ssl               = false
          + weight              = 100
        }
      + domain {
          + name = "<name>.global.ssl.fastly.net"
        }
    }
Plan: 1 to add, 0 to change, 0 to destroy.
Changes to Outputs:
  + active = (known after apply)

In den letzten Zeilen des Outputs können Sie sehen, dass eine Ressource hinzugefügt und nichts geändert oder gelöscht werden muss.

Der Provider erstellt einen Service, eine Domain und ein Backend (entsprechend den verschachtelten Blöcken in Ihrer Konfiguration). Obwohl Sie aus Sicht von Terraform mehrere Blöcke innerhalb der Ressource fastly_service_v1 definiert haben, muss noch nur eine einzige Ressource erstellt werden.

Sobald Sie den Plan überprüft haben und mit ihm zufrieden sind, wenden Sie ihn an:

$ terraform apply
An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
  + create
Terraform will perform the following actions:
...<snip>...
Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.
  Enter a value:

Sie sollten denselben Output wie zuvor sehen, gefolgt von einer interaktiven Eingabeaufforderung, in der Sie bestätigen müssen, dass Sie mit der Anwendung des Plans einverstanden sind. Geben Sie „yes“ ein und drücken Sie die Eingabetaste. Der übrige Output liefert Status-Updates:

Enter a value: yes
fastly_service_v1.test_service: Creating...
fastly_service_v1.test_service: Still creating... [10s elapsed]
fastly_service_v1.test_service: Still creating... [20s elapsed]
fastly_service_v1.test_service: Creation complete after 29s
[id=2Z2KJsHtnsNGkGpafGVdbx]
Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
Outputs:
active = 1

Beachten Sie den Abschnitt „Outputs“ am unteren Rand der obigen Abbildung, in dem die aktive Output-Variable angezeigt wird, die Sie in main.tf definiert haben. Der Wert 1 gibt an, dass die soeben erstellte Serviceversion 1 ist.

HINWEIS: Sie können die manuelle Eingabe von „yes“ überspringen, wenn Sie dazu aufgefordert werden (zum Beispiel bei Verwendung von Terraform in einer automatisierten Umgebung wie einem CI-System), indem Sie

<u>-auto-approve</u>
undefined als Flag an den Unterbefehl apply übergeben.

Validieren Sie Ihre Konfiguration

Während Sie mit den Servicekonfigurationen experimentieren, können Sie Ihre Änderungen mit einer speziellen Test-URL validieren, die Fastly basierend auf der für Ihren Service definierten Domain generiert:

https://<name>.global.ssl.fastly.net

Wenn zum Beispiel der ursprüngliche Terraform Code (mit example als <name> der Domain) erfolgreich angewendet wurde, würde die Test-URL folgendermaßen lauten:

https://example.global.ssl.fastly.net

Es kann bis zu 60 Sekunden dauern, bis die neuen Konfigurationseinstellungen wirksam werden. Sobald die Einstellungen übernommen wurden, werden Ihnen dieselben Inhalte wie auf https://httpbin.org/ angezeigt, wenn Sie die Test-URL aufrufen, da die Domain als Backend konfiguriert wurde. Und obwohl für die Serviceressource im Terraform Code kein individueller VCL-Code definiert wurde, wird Fastlys Standardcode verwendet. Im Standard-VCL sind nützliche und sichere Standardverhaltensweisen enthalten, sodass alle eingehenden Anfragen an das angegebene Backend weitergeleitet (und die Antworten automatisch gecacht) werden.

Modifizieren Sie die Konfiguration

Als Nächstes modifizieren wir den Terraform Code, um einen neuen Block hinzuzufügen. Dieser neue Block wird innerhalb der Ressource fastly_service_v1 hinzugefügt und stellt eine eigene individuelle VCL-Datei dar. Hier können Sie Ihrer Kreativität freien Lauf lassen. Schreiben Sie eine individuelle VCL-Datei, die eine beliebige Logik enthält, die Sie auf der Edge ausführen möchten. Für diese Demo verwenden wir allerdings eine einfache Datei. 

Erstellen Sie zunächst ein vcl-Verzeichnis in dem Verzeichnis, in dem auch Ihre main.tf liegt, und fügen Sie diesem neuen Verzeichnis eine Datei main.vcl hinzu:

$ mkdir vcl && touch vcl/main.vcl

Fügen Sie anschließend folgenden VCL-Code zur Datei main.vcl hinzu:

sub vcl_recv {
  #FASTLY recv
  if (req.url.path == "/anything/here") {
    set req.http.X-CustomHeader = "example";
  }
  if (req.url.path == "/anything/not/found") {
    error 600;
  }
  return(lookup);
}
sub vcl_error {
  #FASTLY error
  if (obj.status == 600) {
    set obj.status = 404;
    set obj.http.Content-Type = "text/html";
    synthetic {"<h1>Not Found</h1>"};
    return(deliver);
  }
}

Dieses individuelle VCL ist simpel, aber zeigt, dass VCL-Updates auch mit Terraform verwaltet werden können. Dieser Code enthält zwei verschiedene Logiken:

  1. Wenn ein Request für /anything/here eingeht, füge einen nutzerdefinierten HTTP-Header hinzu (httpbin.org gibt für alle Pfade, die mit /anything/ beginnen, die Antwort 200 OK sowie eine JSON-Antwort mit den Anfragedetails zurück).

  2. Wenn ein Request für /anything/not/found eingeht, gib die synthetische Antwort 404 Not Found anstelle der Antwort 200 OK zurück, die üblicherweise von httpbin zurückgegeben wird.

HINWEIS: Probieren Sie Fastly Fiddle aus, wenn Sie Hilfe beim Schreiben und Testen von individuellem VCL benötigen, oder erfahren Sie mehr über VCL in unserem Developer Hub.

Aktualisieren Sie als Nächstes den Terraform Code, sodass die Ressource fastly_service_v1 einen

<u>vcl</u>
-Block enthält:

resource "fastly_service_v1" "test_service" {
  ...<snip>...
  vcl {
    content = file("vcl/main.vcl")
    main    = true
    name    = "custom_vcl"
  }
  ...<snip>...
}

Wenn Sie diese Änderungen vorgenommen haben, können Sie die Befehle plan und apply erneut ausführen:

$ terraform plan

Der Output spiegelt das Hinzufügen des vcl-Blocks wider:

fastly_service_v1.test_service: Refreshing state...[id=2Z2KJsHtnsNGkGpafGVdbx]
An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
  ~ update in-place
Terraform will perform the following actions:
  # fastly_service_v1.test_service will be updated in-place
  ~ resource "fastly_service_v1" "test_service" {
        id             = "2Z2KJsHtnsNGkGpafGVdbx"
        name           = "An Example Service"
        # (5 unchanged attributes hidden)
     + vcl {
          + content = <<-EOT
                sub vcl_recv {
                  #FASTLY recv
                  if (req.url.path == "/anything/here")
                    set req.http.X-CustomHeader = "example";
                  }
                  if (req.url.path == "/anything/not/found")
                    error 600;
                  }
                  return(lookup);
                }
                sub vcl_error {
                  #FASTLY error
                  if (obj.status == 600) {
                    set obj.status = 404;
                    set obj.http.Content-Type = "text/html";
                    synthetic {"<h1>Not Found</h1>"};
                    return(deliver);
                  }
                }
            EOT
          + main    = true
          + name    = "custom_vcl"
        }
        # (2 unchanged blocks hidden)
    }
Plan: 0 to add, 1 to change, 0 to destroy.

Das Erste, was Ihnen dabei auffallen sollte, ist „Refreshing state...“. Der Terraform Status bildet einen Cache Ihrer Infrastruktur und Konfiguration. Er wird verwendet, um die in Ihrer Terraform Konfiguration definierten Anforderungen mit der realen Umgebung zu vergleichen. Durch das Aktualisieren dieses Status kann Terraform einen Ausführungsplan mit der aktuellsten Ansicht der Ressourcen berechnen.

Als Nächstes sollte Ihnen auffallen, dass in der letzten Zeile eine Änderung anzeigt wird, die vorgenommen werden muss. Terraform teilt Ihnen mit, dass die Ressource fastly_service_v1 in-place aktualisiert wird (zur visuellen Darstellung dieser Statusänderung wird eine Tilde ~ verwendet). 

Der Diff-Output zeigt auch an, dass einige der vorhandenen geschachtelten Blöcke unverändert sind, und ein +-Zeichen gibt an, welche Zeilen neu sind. Die Terraform Konfiguration hat die Funktion file verwendet, um auf die VCL-Datei im Projektverzeichnis zuzugreifen. Bei der Berechnung des Plans hat Terraform für den Inhalt der Datei allerdings eine Inline-Funktion verwendet, die im Diff-Output angezeigt wird.

Wenn Sie mit dem Ausführungsplan von Terraform zufrieden sind, wenden Sie die Änderungen an (versuchen Sie dieses Mal, das Flag --auto-approve zu verwenden, um zu vermeiden, dass Sie „yes“ manuell eingeben müssen):

$ terraform apply --auto-approve

Nachdem die Änderungen übernommen wurden, dauert es etwa 20 Sekunden, bis die aktualisierte Konfiguration in unserem gesamten Netzwerk bereitgestellt wird und die im VCL-Code definierten Endpunkte entsprechend den neuen Regeln reagieren.

Für den ersten Pfad (/anything/here) wird der nutzerdefinierte Header "X-Customheader": "example" in der JSON-Antwort angezeigt, die von httpbin.org gesendet wird, während der zweite Pfad (/anything/not/found) nun eine synthetische 404 Not Found-Antwort zurückgibt, die vom VCL-Code generiert wurde. Die Servicekonfiguration und der VCL-Code funktionieren also wie erwartet.

Das war’s! Hier nochmal eine kurze Zusammenfassung: Sie haben mithilfe der Terraform Konfiguration nutzerdefinierte Anforderungen für einen Fastly Service festgelegt, einen Ausführungsplan erstellt und den Plan angewendet, um die Erstellung echter Fastly Ressourcen auszulösen. Anschließend haben Sie einen typischen Update-Lifecycle durchgeführt, bei dem Sie vollständige Kontrolle und Transparenz über die Änderungen an Ihren Serviceressourcen hatten. 

Nächste Schritte

Die Verwaltung von VCL ist nur eine Möglichkeit, Terraform und Fastly gemeinsam zu nutzen. Sie können auch Compute@Edge Services verwalten, die sich die Power von WebAssembly zunutze machen, um sichere, nutzerdefinierte Binärdateien aus Sprachen wie Rust und AssemblyScript auszuführen. Weitere Tipps, wie Sie mit Compute@Edge und Terraform noch mehr aus Fastly herausholen können, finden Sie in „Orchestrierung mit Terraform und dem Fastly Terraform Provider” und der Fastly Terraform Dokumentation.

Mark McDonnell
Staff Software Engineer, Developer Relations
Veröffentlicht am

Lesedauer: 8 Min.

Sie möchten sich mit einem Experten austauschen?
Sprechen Sie mit einem Experten
Diesen Beitrag teilen
Mark McDonnell
Staff Software Engineer, Developer Relations

Mark (er/ihm/ihn) ist ein einfühlsamer Zuhörer, mehrsprachiger Programmierer und Autor mehrerer Fachbücher. In den vergangenen 20 Jahren arbeitete er unter anderem als Staff Software Engineer bei BuzzFeed und als Principal Engineer für BBC News. Vor allem aber ist Mark Ehemann, Vater und Musikliebhaber.

Sie möchten loslegen?

Setzen Sie sich mit uns in Verbindung oder erstellen Sie einen Account.