Terraformer - Infrastruktur zum Codieren

Bild
Ich möchte über das neue CLI-Tool sprechen, das ich geschrieben habe, um ein altes Problem zu lösen.

Das Problem


Terraform ist seit langem der Standard in der Devops / Cloud / IT-Community. Das Ding ist sehr praktisch und nützlich, um Infrastruktur als Code zu machen. Es gibt viele Reize in Terraform sowie viele Gabeln, scharfe Messer und Rechen.
Mit Terraform ist es sehr praktisch, neue Dinge zu tun und sie dann zu verwalten, zu ändern oder zu löschen. Und was ist mit denen, die eine riesige Infrastruktur in der Cloud haben und nicht über Terraform erstellt wurden? Das Umschreiben und Neuerstellen der gesamten Cloud ist irgendwie teuer und unsicher.
Ich bin in 2 Werken auf ein solches Problem gestoßen. Das einfachste Beispiel ist, wenn Sie möchten, dass alles in Form von Terraform-Dateien vorliegt, Sie über 250 Eimer verfügen und viele davon mit Ihren Händen für Terraform schreiben.
Es gibt seit 2014 ein Problem in terrafom, das 2016 mit der Hoffnung geschlossen wurde, dass es Import geben wird.

Im Allgemeinen ist alles wie auf dem Bild nur von rechts nach links


Warnungen: Der Autor lebt sein halbes Leben nicht in Russland und schreibt wenig auf Russisch. Vorsicht Rechtschreibfehler.

Lösungen


1. Es gibt schlüsselfertige und alte Lösungen für AWS Terraforming . Als ich versuchte, meinen 250+ Eimer durchzubringen, stellte ich fest, dass dort alles schlecht war. AWS hat bereits seit langer Zeit viele neue Optionen eingeführt, und Terraforming kennt sie nicht. Im Allgemeinen gibt es eine Ruby- Vorlage, die schlecht aussieht . Nach zwei Uhr abends schickte ich eine Pull-Anfrage , um dort weitere Funktionen hinzuzufügen, und stellte fest, dass eine solche Lösung überhaupt nicht passt.
Wie Terraforming funktioniert, nimmt es Daten aus dem AWS SDK und generiert tf und tfstate über die Vorlage.
Es gibt 3 Probleme:
1. Bei Updates treten immer Rückstände auf
2. tf-Dateien gehen manchmal kaputt aus
3. tfstate wird getrennt von tf gesammelt und konvergiert nicht immer
Im Allgemeinen ist es schwierig, ein Ergebnis zu erhalten, bei dem der "Terraform-Plan" besagt, dass es keine Änderungen gibt

2. `terraform import` - ein in terraform integrierter Befehl. Wie funktioniert es
Sie schreiben eine leere TF-Datei mit dem Namen und Typ der Ressource, führen dann den Terraform-Import aus und übergeben die ID der Ressource. terraform ruft den Provider an, empfängt die Daten und erstellt eine tfstate-Datei.
Es gibt 3 Probleme:
1. Wir erhalten nur die tfstate-Datei und die tf leer muss mit tfstate geschrieben oder konvertiert werden
2. Kann jedes Mal nur mit einer Ressource arbeiten und unterstützt nicht alle Ressourcen. Und was soll ich nochmal mit 250+ Eimer machen
3. Sie müssen die Ressourcen-ID kennen - das heißt, Sie müssen sie in Code einschließen, der eine Liste von Ressourcen abruft
Im Allgemeinen ist das Ergebnis teilweise und lässt sich nicht gut skalieren

Meine Entscheidungen

Anforderungen:
1. Möglichkeit, tf- und tfstate-Dateien nach Ressourcen zu erstellen. Laden Sie zum Beispiel alle Buckets / Sicherheitsgruppen / Load Balancer herunter und der "Terraform-Plan" gibt zurück, dass es keine Änderungen gibt
2. Es sind 2 GCP + AWS-Wolken erforderlich
3. Eine globale Lösung, die jedes Mal einfach zu aktualisieren ist und nicht 3 Arbeitstage lang Zeit für jede Ressource verschwendet
4. Open Source machen - jeder hat ein solches Problem

Go-Sprache - deshalb liebe ich sie und sie hat eine Bibliothek zum Erstellen von HCL-Dateien, die in Terraform verwendet wird, + viel Code in Terraform, was nützlich sein kann

Der Weg


Erster Versuch
Startete eine einfache Option. Zugriff auf die Cloud über das SDK für die gewünschte Ressource und Konvertierung in Terraform-Felder. Der Versuch ist sofort für die Sicherheitsgruppe gestorben, weil ich 1,5 Tage nicht mochte, um nur die Sicherheitsgruppe zu konvertieren (und es gibt viele Ressourcen). Lange und dann Felder können geändert / hinzugefügt werden

Zweiter Versuch
Basierend auf der hier beschriebenen Idee. Nehmen Sie einfach tfstate und konvertieren Sie es in tf. Alle Daten sind vorhanden und die Felder sind gleich. Wie bekomme ich den vollen Status für viele Ressourcen? Dann kam der Befehl "Terraform Refresh" zur Rettung. terraform nimmt alle Ressourcen in tfstate und zieht die Daten nach ID und schreibt alles in tfstate. Das heißt, erstellen Sie einen leeren Status mit nur Namen und IDs, führen Sie "Terraform Refresh" aus und wir erhalten den vollständigen Status. Hurra!
Lassen Sie uns nun die rekursive Pornografie machen , einen Konverter für tfstate to tf zu schreiben. Für diejenigen, die tfstate noch nie gelesen haben, ist dies JSON, aber etwas Besonderes.
Hier sind die wichtigen Teileattribute
"attributes": { "id": "default/backend-logging-load-deployment", "metadata.#": "1", "metadata.0.annotations.%": "0", "metadata.0.generate_name": "", "metadata.0.generation": "24", "metadata.0.labels.%": "1", "metadata.0.labels.app": "backend-logging", "metadata.0.name": "backend-logging-load-deployment", "metadata.0.namespace": "default", "metadata.0.resource_version": "109317427", "metadata.0.self_link": "/apis/apps/v1/namespaces/default/deployments/backend-logging-load-deployment", "metadata.0.uid": "300ecda1-4138-11e9-9d5d-42010a8400b5", "spec.#": "1", "spec.0.min_ready_seconds": "0", "spec.0.paused": "false", "spec.0.progress_deadline_seconds": "600", "spec.0.replicas": "1", "spec.0.revision_history_limit": "10", "spec.0.selector.#": "1", 

Es gibt:
1. id - string
2. Metadaten - ein Array der Größe 1 und darin ein Objekt mit Feldern, das unten beschrieben wird
3. spec - Hash der Größe 1 und darin Schlüssel, Wert
Kurz gesagt, ein unterhaltsames Format, alles kann auch auf mehreren Ebenen vertieft werden
  "spec.#": "1", "spec.0.min_ready_seconds": "0", "spec.0.paused": "false", "spec.0.progress_deadline_seconds": "600", "spec.0.replicas": "1", "spec.0.revision_history_limit": "10", "spec.0.selector.#": "1", "spec.0.selector.0.match_expressions.#": "0", "spec.0.selector.0.match_labels.%": "1", "spec.0.selector.0.match_labels.app": "backend-logging-load", "spec.0.strategy.#": "0", "spec.0.template.#": "1", "spec.0.template.0.metadata.#": "1", "spec.0.template.0.metadata.0.annotations.%": "0", "spec.0.template.0.metadata.0.generate_name": "", "spec.0.template.0.metadata.0.generation": "0", "spec.0.template.0.metadata.0.labels.%": "1", "spec.0.template.0.metadata.0.labels.app": "backend-logging-load", "spec.0.template.0.metadata.0.name": "", "spec.0.template.0.metadata.0.namespace": "", "spec.0.template.0.metadata.0.resource_version": "", "spec.0.template.0.metadata.0.self_link": "", "spec.0.template.0.metadata.0.uid": "", "spec.0.template.0.spec.#": "1", "spec.0.template.0.spec.0.active_deadline_seconds": "0", "spec.0.template.0.spec.0.container.#": "1", "spec.0.template.0.spec.0.container.0.args.#": "3", 

Wenn Sie eine Programmieraufgabe für ein Interview wünschen, bitten Sie im Allgemeinen darum, einen Parser für diese Angelegenheit zu schreiben :)
Nach langen Versuchen, einen Parser ohne Fehler zu schreiben, fand ich einen Teil davon im Terraform-Code und den wichtigsten Teil. Und alles schien gut zu funktionieren

Versuch drei
Der Terraform-Anbieter ist eine Binärdatei, in der ein Code mit allen Ressourcen und Logik für die Arbeit mit der Cloud-API vorhanden ist. Jede Cloud hat ihren eigenen Anbieter und Terraform selbst ruft sie nur über ihr RPC-Protokoll zwischen zwei Prozessen auf.
Jetzt habe ich mich entschlossen, über RPC-Aufrufe direkt auf Terraform-Anbieter zuzugreifen. Es stellte sich als wunderschön heraus und ermöglichte es, Terraform-Anbieter auf neuere umzustellen und neue Möglichkeiten zu erhalten, ohne den Code zu ändern. Es stellte sich heraus, dass nicht alle Felder in tfstate in tf sein sollten, aber wie kann ich das herausfinden? Fragen Sie einfach den Anbieter danach. Dann begann eine weitere rekursive Pornografie über die Zusammenstellung regulärer Ausdrücke mit der Suche nach Feldern innerhalb von tfstate auf allen Ebenen der Tiefe.

Am Ende haben wir ein nützliches CLI-Tool, das eine gemeinsame Infrastruktur für alle Terraform-Anbieter hat, und Sie können ganz einfach eine neue hinzufügen. Auch das Hinzufügen von Ressourcen nimmt wenig Code in Anspruch. Plus alle Arten von Extras wie die Verbindung zwischen Ressourcen. Natürlich gab es viele verschiedene Probleme, die nicht alle beschrieben werden können.
Er nannte das kleine Tier Terrafomer.

Finale


Mit Terrafomer haben wir aus zwei Wolken 500-700.000 Zeilen tf + tfstate-Code generiert. Sie könnten Legacy-Dinge aufnehmen und sie nur durch Terraform berühren, wie dies bei den besten Ideen der Infrastruktur als Code der Fall ist. Es ist einfach magisch, wenn Sie eine riesige Wolke nehmen und sie durch den Befehl in Form von Terraform-Arbeitsdateien erhalten. Und dann grep / replace / git und so weiter.

Er kämmte und ordnete, erhielt die Erlaubnis. Veröffentlicht am Donnerstag (05.02.19) für alle auf Github. github.com/GoogleCloudPlatform/terraformer
Bereits 600 Sterne erhalten, 2 Pull-Anfragen zur Unterstützung von Openstack und Kubernetes. Gute Bewertungen. Im Allgemeinen ist das Projekt für Menschen nützlich
Ich rate allen, die mit Terraform arbeiten möchten und nicht alles dafür neu schreiben möchten.
Ich würde gerne Anfragen, Probleme, Sterne ziehen.

Demo


Updates: Die minimale Openstack-Unterstützung und die Unterstützung von Kubernetes sind dank PR-Mitarbeitern fast fertig

Source: https://habr.com/ru/post/de450410/


All Articles