Bereits Kunde? Jetzt einloggen.
Lesezeit ca. 9 Min.

Terraform: Alles ist Code


Linux Magazin - epaper ⋅ Ausgabe 12/2019 vom 07.11.2019

Infrastrukturmanagement in Multiclouds mit Terraform


Beim Cloud-Konfigurationsmanagement sind Tools wie Puppet, Chef oder Ansible heute Standard. In Multi-Cloud-Szenarien bedarf aber auch das Verwalten der darunterliegenden Infrastruktur der Automatisierung. Terraform ist dafür das ideale Werkzeug.

Artikelbild für den Artikel "Terraform: Alles ist Code" aus der Ausgabe 12/2019 von Linux Magazin. Dieses epaper sofort kaufen oder online lesen mit der Zeitschriften-Flatrate United Kiosk NEWS.

Bildquelle: Linux Magazin, Ausgabe 12/2019

Als Hybrid-Cloud bezeichnet man die Kombination aus einer oder mehreren Public und Private Clouds, also die Zusammenarbeit einer Cloud-Lösung im eigenen Rechenzentrum mit einer Cloud eines externen Anbieters (Abbildung 1 ). Eine Multicloud besteht hingegen aus mehreren Clouds unterschiedlicher Anbieter ( ...

Weiterlesen
epaper-Einzelheft 5,99€
NEWS 14 Tage gratis testen
Bereits gekauft?Anmelden & Lesen
Leseprobe: Abdruck mit freundlicher Genehmigung von Linux Magazin. Alle Rechte vorbehalten.

Mehr aus dieser Ausgabe

Titelbild der Ausgabe 12/2019 von Randphänomen. Zeitschriften als Abo oder epaper bei United Kiosk online kaufen.
Randphänomen
Titelbild der Ausgabe 12/2019 von Magnet Kubernetes. Zeitschriften als Abo oder epaper bei United Kiosk online kaufen.
Magnet Kubernetes
Titelbild der Ausgabe 12/2019 von News: Kurznachrichten. Zeitschriften als Abo oder epaper bei United Kiosk online kaufen.
News: Kurznachrichten
Titelbild der Ausgabe 12/2019 von Zahlen & Trends. Zeitschriften als Abo oder epaper bei United Kiosk online kaufen.
Zahlen & Trends
Titelbild der Ausgabe 12/2019 von Ansible: Aus einem Guss. Zeitschriften als Abo oder epaper bei United Kiosk online kaufen.
Ansible: Aus einem Guss
Titelbild der Ausgabe 12/2019 von Bitparade: In eigener Sache: DELUG-DVD: Ubuntu 19.10, All Systems Go!. Zeitschriften als Abo oder epaper bei United Kiosk online kaufen.
Bitparade: In eigener Sache: DELUG-DVD: Ubuntu 19.10, All Systems Go!
Vorheriger Artikel
Ansible: Aus einem Guss
aus dieser Ausgabe
Nächster Artikel Bitparade: In eigener Sache: DELUG-DVD: Ubuntu 19.10, All Systems…
aus dieser Ausgabe

Als Hybrid-Cloud bezeichnet man die Kombination aus einer oder mehreren Public und Private Clouds, also die Zusammenarbeit einer Cloud-Lösung im eigenen Rechenzentrum mit einer Cloud eines externen Anbieters (Abbildung 1 ). Eine Multicloud besteht hingegen aus mehreren Clouds unterschiedlicher Anbieter (Abbildung 2 ) oder auch nur aus verschiedenen Cloud-Lösungen, die mittels APIs über VPNs untereinander Daten austauschen.
Damit ergibt sich eine Landschaft unterschiedlicher virtueller Ressourcen, die zum Teil Drittanbieter bereitstellen und betreuen. In der Regel betrifft das die Hardware, oft auch das regelmäßige Update von Software oder die Datensicherung. Die Motive für eine Multicloud sind vielfältig. So bietet kein Anbieter alle Features, der Anwender muss sich unter Umständen die benötigten Komponenten bei mehreren Providern zusammensuchen. Auch unterschiedliche Preismodelle können hier eine Rolle spielen. Ein weiteres Motiv besteht darin, sich seine Unabhängigkeit zu bewahren und kurzfristig den Anbieter wechseln zu können. Allerdings gilt es in einem solchen Fall, größere Mengen von Daten zu bewegen. Unangenehm wird es, wenn der Anwender dann eventuell unterschiedliche Formate, etwa von VMs, erst konvertieren muss. Selbst bei weit ausgebauter Automatisierung müssen am Ende immer noch die Nutzdaten übertragen werden.
Die Konfiguration der Software in einer VM oder in einem Container übernehmen die schon erwähnten Automatisierungswerkzeuge. Für die darunterliegende Infrastruktur steht Terraform bereit, das die Firma HashiCorp[1] entwickelt und unter der Mozilla Public License 2.0[2] bereitstellt. Es eignet sich besonders für heterogene Hybrid- oder Multi-Cloud-Umgebungen. Terraform verwaltet virtuelle Maschinen auf unterschiedlichsten Cloud-Plattformen, die Netzinfrastruktur vom Subnetz über Router bis hin zum Load-Balancer oder der Firewall und alles, was die gewählte Cloud-Lösung darüber hinaus zu bieten hat.

Abbildung 1: Bei einer hybriden Cloud arbeitet immer eine private mit einer oder mehreren öffentlichen Clouds zusammen.


Infrastruktur als Code

Der zugrundeliegende Prozess, der unterschiedliche Ressourcen in Deklarationen beschreibt, nennt sich Infrastructure as Code. Auf Basis dieser Beschreibung kümmert sich Terraform dann um das Management der benötigten Ressourcen, erstellt oder löscht sie und kümmert sich um Statusänderungen. Abhängigkeiten berücksichtigt es dabei implizit. Terraform deklariert Ressourcen im eigenen HCL-Format (HashiCorp Language), einem erweiterten JSON, das zusätzlich Dokumentation ermöglicht und die Lesbarkeit vereinfacht. Auch natives JSON wird unterstützt, ist jedoch vor allem Neulingen nicht zu empfehlen.
Die Deklaration der benötigten Ressourcen mittels HCL in gewöhnlichen Textdateien bietet gegenüber der Konfiguration mithilfe einer Webkonsole oder mit Werkzeugen des Herstellers einige entscheidende Vorteile. Zum einen lässt sich so auf einfache Weise die gesamte Konfiguration teilen und mithilfe eines Versionskontrollsystems wie Git nachvollziehbar und sicher speichern. Zum anderen kann man aus der gespeicherten Konfiguration jederzeit schnell und vollautomatisch eine reproduzierbare Arbeitsumgebung aufbauen. Die große Stärke von Terraform liegt darin, dass es eine Vielzahl von Cloud- und Infrastrukturanbietern unterstützt und so die große Lücke schließt, die fehlende Standards verursacht haben.

Provider

Die Verwaltung in einer Multi- oder Hybrid-Cloud bewerkstelligt Terraform über sogenannte Provider. Als Provider bezeichnet man die grundlegende Abstraktionsschicht zur Steuerung und zur Authentifizierung gegenüber der API der zu verwaltenden Lösung. Solche Provider stellt HashiCorp für die Clouds aller großen Anbieter standardmäßig bereit[3] . Aber auch für das nicht proprietäre Open-Stack, das kleinere, regionale Anbieter gern einsetzen und das auch für die eigene Private Cloud infrage kommt, gibt es einen solchen Provider.

Abbildung 2: Eine Multicloud besteht aus Private und/ oder Public Clouds verschiedener Anbieter, die über VPNs verbunden sind.


Idealerweise legt der Systemadministrator seine Provider in einer Datei »provider.tf« im eigenen Projektverzeichnis ab. WieListing 1 demonstriert, unterscheiden sich die Attribute der Ressourcen aufgrund der unterschiedlichen Strukturen in der jeweiligen Implementation. Open-Stack setzt beispielsweise immer ein Projekt (»tenant_name«) voraus, Amazon Web Service (AWS) hingegen arbeitet benutzerbezogen.
Die Unterschiede bei den Ressourcentypen und auch bei den Features der Anbieter sind noch viel ausgeprägter als die Unterschiede zwischen den Providern inListing 1 . Auch wer Terraform verwendet, muss hier mit einem erhöhten Aufwand bei der Codeerzeugung für die eigene Infrastruktur rechnen. Das verhindert eine vollständige Abstraktion; stattdessen muss man die unterschiedlichen Ressourcentypen pro Provider individuell konfigurieren. Das ließe sich dadurch reduzieren, dass sich der Anwender für Anbieter entscheidet, die auf dieselbe Cloud-Implementierung setzen. In diesem Fall wird lediglich ein weiterer Provider benötigt (Listing 2 ).
Genauso verfährt, wer zwar mit denselben Anbietern arbeitet, aber unterschiedliche Standorte für Ressourcen braucht. Diese Beziehung definiert das Attribut »region«. Ressourcen ordnet man durch Setzen des Metaparameters »provider« dem entsprechenden Provider zu. Fehlt bei einer Ressource die Angabe des Providers, benutzt Terraform den Default-Provider, also denjenigen ohne einen Alias. Die verwendeten Variablen, wie »var.openstack_ projekt« in den Provider-Definitionen, definiert man gemeinhin in einer gesonderten Datei »variables.tf« (Listing 3 ) oder gibt sie beim Aufruf von Terraform mit an. Da es sich um sicherheitskritische Informationen handelt, sind hier die Environment-Variablen der Shell (Listing 4 ) zu bevorzugen.

Damit dem Anwender stets eine funktionierende Infrastruktur zur Verfügung steht, trennt Terraform das Ermitteln der notwendigen Operationen von der tatsächlichen Umsetzung. Dadurch lassen sich Konfigurationsbeschreibungen ohne Risiko vorab verifizieren. Das vermeidet ein versehentliches Löschen oder Verändern oder minimiert die Folgen.

Drei Phasen des Lebenszyklus

Die in HCL beschriebene Infrastruktur durchläuft in ihrem Lebenszyklus immer die drei Schritte »terraform plan«, »terraform apply« und »terraform destroy«.

Im ersten Schritt löst Terraform beschriebene Ressourcen auf und bringt sie mittels graphentheoretischer Algorithmen in die richtige Reihenfolge.
Die Konfiguration, die der Admin in willkürlicher Reihenfolge notiert hat, sortiert die Software nach den enthaltenen Abhängigkeiten und ermittelt gleichzeitig den optimalen Ausführungsweg. Beispielsweise gilt es, zuerst ein Netzwerksegment zu erstellen, bevor sich einer VM eine IP-Adresse zuordnen lässt, die wiederum für die DNS-Konfiguration nötig ist. Der Admin erfährt also sofort, was das Abarbeiten des Plans erfordert und welche Ressourcen in welcher Reihenfolge angelegt werden.

Die Phase »terraform apply« setzt den vorher erstellten Plan um und legt die jeweiligen Ressourcen an beziehungsweise löscht oder modifiziert sie. Vor jeder Ausführung von »plan« oder »apply« ermittelt Terraform den aktuellen Zustand des Zielsystems, um notwendige Änderungen mit dem aktuellen Status abzugleichen. Diesen Status speichert es in eine lokale Statusdatei »terraform.tfstate« im Projektverzeichnis. Terraform benötigt sie, um Cloud-Ressourcen mit den lokalen Definitionen zu vergleichen und das Mapping von beschriebenen auf reale Ressourcen zu generieren[4] . Teamarbeiter sollten die Statusdatei zentral speichern.
Zu guter Letzt löscht »terraform destroy« die in Terraform verwalteten (also die im Statefile enthaltenen) Ressourcen aus den Zielsystemen.

Ein Beispiel

Im Folgenden sollen Webserver als Beispiel dienen, die ein Nutzer sowohl bei Amazon hostet als auch bei einem Anbieter, der OpenStack einsetzt. Dazu konfiguriert er die Provider so, wie inListing 1 ,2 und 4 gezeigt. Da der Systemadministrator Zugang zu den Maschinen benötigt, deklariert er je eine Ressource für den öffentlichen Schlüssel des Admins. Er muss zwei dieser Ressourcen anlegen, da jeder Provider seine eigenen Ressourcentypen mitbringt und auch die Attribute unterschiedliche Namen tragen. Die Online-Referenz[5] beschreibt die unterschiedlichen Ressourcentypen umfassend.
Die Attribute »key_name« beziehungsweise »name« geben die Namen an, mit denen später auf diese Ressourcen Bezug genommen wird. Für die interne Bezeichnung lässt sich hingegen in beiden Fällen mit »public_key« derselbe Name wählen. Beide Anbieter stellen einen Router und ein aus dem privaten IP-Adressbereich bestehendes Subnetz zur Verfügung. Für den Zugang aus dem Internet übersetzt der Router eine öffentliche IP-Adresse mittels Destination Network Address Translation (DNAT) in die private Adresse des jeweiligen Hosts. Damit überhaupt ein Login via SSH erfolgen kann, muss der Admin bei beiden Anbietern der Paketfilter für eingehenden Datenverkehr auf Port 22/ TCP konfigurieren (Listing 6 ).

Für die internen Namen wie auch die referenzierenden Bezeichner gilt dasselbe wie bei den beiden Keypair-Ressourcen. Der CIDR-Block schränkt den Zugang nicht auf bestimmte Zieladressen ein, somit ist der Zugang zum SSH-Standard-Port für die beiden privaten Netze erlaubt.

Module

Die virtuellen Maschinen und vor allem deren Anzahl lassen sich gut über Terraform-Module verwalten. Ein Modul besteht aus einer oder mehreren Terraform-Dateien, die in einem gesonderten Verzeichnis liegen müssen. Die Ressourcen, die ein Modul verwaltet, lassen sich mehrfach nutzen. Dafür versieht der Admin das Modul einfach mit einem anderen Bezeichner. Welches Modul zu verwenden ist, gibt er über die Pfadangabe zum Modulverzeichnis mithilfe des Attributs »source« an (Listing 7 ).
Die VM-Instanzen erfordern bei AWS und OpenStack getrennte Module. Alle Attribute außer »source« sind Parameter des Moduls, die der Anwender selbst bestimmen kann, vorausgesetzt, er schreibt das Modul selbst. Unter »registry.terraform.io« stehen aber auch eine Vielzahl vorgefertigter Module zum Herunterladen bereit, so auch die für die hier beschriebene Aufgabe.
Neben der Angabe, welches Basis-Image es auszurollen gilt, finden sich hier auch die Referenzen auf die oben deklarierten Objekte vom Typ Security Group und SSH-Key. Der Parameter »instance_count« gibt die Anzahl der zu provisionierenden VMs an, im Beispiel vonListing 7 jeweils zwei für beide Provider. Hier gibt es einen Unterschied zwischen AWS und OpenStack: Bei Letzterem darf der Admin den Hostnamen der VM setzen, bei diesem Modul mit dem Attribut »instance_ name«. Freilich sollen nicht beide Instanzen »web« heißen; der Name dient lediglich als Basis und bekommt noch ein Suffix in Form einer Ziffer. Bei zwei Instanzen ergeben sich also die Namen »web0« und »web1«.
Da die Software die öffentlichen IP-Adressen dynamisch vergibt, definiert der Anwender hier einen Output, der mit »terraform output« die vergebenen Adressen ausgibt. Als Grundlage dient jeweils die Ausgabe der beiden Module für »public_ip«. Das Ergebnis ist jeweils eine Liste, die mit der Funktion »concat« zu einer gemeinsamen Liste zusammengefasst wird.
Listing 8 bis 10 zeigen die Dateien des AWS-Server-Moduls,Listing 11 bis 14 jene des OpenStack-Servers. Die Parameter eines Moduls definiert der Admin über Variablen. Fehlt eine Vorgabe, handelt es sich um einen Parameter, der beim Modulaufruf zu setzen ist.
Bei AWS muss sich der Admin nur um die Instanz selbst kümmern, da standardmäßig eine öffentliche IP-Adresse zu jeder Instanz vergeben wird – Amazon spricht hier von Elastic-IP. Der Metaparameter »count« implementiert eine For-Schleife über die gesamte Ressource. Dabei hängt Terraform den »count.index« als Laufparameter automatisch an den Ressourcennamen an, inListing 9 beispielsweise »this[0]«, »this[1]« und so weiter.
Listing 10 enthält den Output des Moduls »aws_server«, der schon inListing 7 Verwendung fand. Als alternative Schreibweise für »this[*]« kommt »this.*« zum Einsatz. Die Rückgabe besteht aus einer Liste aller Werte zum Attribut »public_ip« der Ressourcen »aws_instance«, die mittels »count« von diesem Modul erzeugt wurden.
Der Anbieter der OpenStack-Cloud stellt zwar, wie oben erwähnt, ebenfalls einen Router mit DNAT und ein Default-Netz bereit, bietet allerdings nicht automatisch eine öffentliche IP (Floating IP im Open-Stack-Jargon) zu jeder provisionierten Instanz. Das hat zur Folge, dass sich der Admin selbst um eine solche kümmern muss.
Listing 11 definiert analog zum AWS-Modul zunächst die Parameter des Open-Stack-Moduls. Der Hauptteil des Moduls in der Datei »main.tf« (Listing 12 ) unterscheidet sich jedoch erheblich vom AWS-Pendant: So muss man hier der Instanz mitteilen, mit welchen Netz sie sich zu verbinden hat. Das Attribut »network« stellt unter Zuhilfenahme der ID des Netzes die Verknüpfung her.
Da Terraform das Netz nicht selbst angelegt hat, ermittelt man die ID üblicherweise über eine Data-Ressource (Listing 13 ). Damit stellt man die Eigenschaften des Netzwerks mit dem Namen »default« fest und erzeugt ein Terraform-Data-Objekt, das diese Eigenschaften als Attribute enthält, darunter auch die eindeutige ID des Netzes »default«.
Wie schon nach dem Namen »default« des privaten Netzes muss sich der Admin beim Anbieter auch nach dem Namen des öffentlichen Netzes erkundigen, im Allgemeinen über die von ihm zur Verfügung gestellte Konsole. Dieser Name ist im Attribut »pool« des Objekts vom Typ »openstack_networking_floatingip_v2« anzugeben (Listing 14 ). Dieses Objekt verknüpft der Admin dann mit dem der Instanz über ein weiteres Objekt des Typs »openstack_compute_floatingip_associate_ v2«.

Alle drei Ressourcen werden jeweils durch »count« mit einer For-Schleife umgeben. Die zu einer Instanz gehörigen Objekte erhalten damit alle denselben Index und lassen sich so referenzieren.
Nun sollte einem abschließenden »terraform plan« beziehungsweise »apply« nichts mehr im Wege stehen. Vorher steht aber noch der obligatorische Aufruf »terraform init« zum Projektstart an. Er kann auch wiederholt anfallen, wenn der Admin dem Projekt einen neuen Provider oder ein neues Modul hinzufügt.
Zur Komplettierung des vorgestellten Lifecycles bietet die Firma HashiCorp noch diverse andere Produkte, darunter Packer[6] . Im Zusammenspiel mit Vagrant[7] , einem Framework zum Provisionieren und Steuern virtueller Maschinen, lassen sich Images erstellen und testen, die Packer später automatisiert und regelmäßig erzeugt. Sie dienen dann in der Cloud als Images zum Provisionieren neuer Maschinen. Mit anderen Werkzeugen kann der Anwender diesen Prozess sogar vollständig automatisieren. Für diesen Bereich bietet HashiCorp mit Vault[8] , Nomad[9] und Consul[10] entsprechende Lösungen an.

Fazit

Hat man sich erst einmal in Terraform eingearbeitet, verursacht es nur noch wenig Aufwand, damit komplette Infrastrukturen auf Knopfdruck auszurollen und im laufenden Betrieb zu managen. (jcb )

Infos

[1] HashiCorp:[https://www.hashicorp.com]
[2] Mozilla Public License:[https://github.com/hashicorp/terraform/blob/master/LICENSE]
[3] Terraform-Provider:[https://www.terraform.io/docs/providers/index.html]
[4] Terraform-States:[https://www.terraform.io/docs/state/purpose.html]
[5] Terraform-CLI-Dokumentation:[https://www.terraform.io/docs/cli‑index.html]
[6] Packer:[https://github.com/hashicorp/packer]
[7] Vagrant:[https://github.com/hashicorp/vagrant]
[8] Vault:[https://www.vaultproject.io]
[9] Nomad:[https://www.nomadproject.io]
[10] Consul:[https://www.consul.io]

Der Autor

Der Mathematiker Lennart Betz arbeitet seit 2011 als Consultant und als Trainer für die in Nürnberg ansässige Netways GmbH. Seine Hauptaufgabenfelder bei Kunden und als Trainer umfassen Systemüberwachung, Automatisierung und Konfigurationsmanagement.


© welcomia, 123RF