Wie soll ich meine Umgebungsvariablen speichern?

11

Dies ist eine sehr breite Frage zu Methoden und Ratschlägen in Bezug auf Umgebungsvariablen / -strukturen. Aber letztendlich suche ich nach Antworten auf die sehr spezifische Frage: "Wie soll ich meine Umgebungsvariablen speichern?"

Zunächst einige Klarstellungen:

  • Eine Umgebung kann für mich aus 3 bis 10 Servern bestehen und ist eine Möglichkeit, die Infrastruktur eines bestimmten Kunden zu enthalten.
  • In jeder Umgebung gibt es einige Variablen, die meist automatisch aus einigen Schlüsseleingaben (Name, Größe usw.) generiert werden.

Derzeit speichern wir alle unsere Umgebungsvariablen in einer Struktur wie der folgenden:

<playbook>.yml                   # Various playbooks for deployment
roles/windows                    # Ansible role for Ubuntu
roles/ubuntu                     # Ansible role for Ubuntu
config/hosts/<name>.yml          # Ansible inventory
config/hosts/vars/<name>.json    # Environment specific variables 

Im Moment wird die Konfiguration als Submodul im obigen Git-Repository initialisiert. Da sich die Variablendatei ziemlich häufig ändert, hat dies zu Problemen mit der Änderung der Daten geführt, die ein-, zweimal oder sogar dreimal zwischen den Festschreibungen liegen, wodurch es immer schwieriger wird, Änderungen nachzuverfolgen.

Wie ich persönlich sehe, sollten wir , alle unsere zentral / skalierbar zu speichern und uns dann mit einem dynamischen Inventar mit .

Ich verstehe, dass es einige Technologien gibt, die einen Teil dessen leisten, was erforderlich sein könnte, wie z. B. Consul, aber sie scheinen am besten in einer Umgebung zu funktionieren, die nur eine große Anwendung bedient, anstatt viele kleinere, leicht unterschiedliche.

Ich sehe im Wesentlichen, dass wir ein Inventarskript schreiben und dann einfach alle unsere Daten in eine nicht speziell erstellte Datenbank schieben müssen und dann so weitermachen müssen, als ob sich nichts geändert hätte. Ich sehe dies möglicherweise als eine Möglichkeit, viele der derzeit gespeicherten Daten möglicherweise zu reduzieren und möglicherweise verschiedene Möglichkeiten zum Speichern der Daten zu untersuchen, anstatt nur zu vergrößern, was sie erneut bereitstellen.

Ich hoffe, jemand hat Erfahrung in der Implementierung von Infrastruktur als Code, wenn er mit vielen kleineren Umgebungen im Gegensatz zu einer, zwei oder drei großen Umgebungen umgehen muss.

Irgendwelche Vorschläge?

Naphta
quelle

Antworten:

13

Ich hatte zwei Versuche, Umgebungsvariablen auf skalierbare Weise zu erstellen, und keiner von beiden hat sich als perfekt erwiesen, da es, wie ich festgestellt habe, sehr schwierig ist, alles richtig zu machen. Ich werde im Folgenden eine Zusammenfassung meiner beiden Erfahrungen geben:

Übliche Faktoren

  • Umgebungsvariablen werden in einem vom ursprünglichen Quellcode getrennten Repository gespeichert (sie sind zusammen submoduliert, basieren jedoch weiterhin auf separaten Repos).
  • Es gibt einen separaten "Build" -Prozess für das Artefakt und seine Variablen.
  • Es gibt keinen separaten Freigabeprozess für die Umgebungsvariablen. Wenn Sie Umgebungsvariablen ändern möchten, müssen Sie dieselben Änderungsprüfungsgremien wie üblich durchlaufen

Verwenden von Consul KV-Paaren

Die Umgebungsvariablen werden aus einem Artefakt-Repository (niemals dem ursprünglichen Git-Repo) geladen und beispielsweise in einen KV-Paarbaum mit Namespace geladen

/env/dev1/my/application/v1.1.1

Wenn das vorhergehende dev1 der Name der Umgebung ist, ist my / application der Anwendungsnamespace und v1.1.1 ist die Version der zu verwendenden Umgebungsvariablen.

Für Entwickler sind all diese Dinge unsichtbar. Zur Laufzeit überprüft die Plattform, ob die Umgebung im aktuellen Konsul-Cluster vorhanden ist (wenn kein Problem vorliegt und Fehler auftreten), überprüft sie den Teilbaum auf den Anwendungsnamespace (auf diese Weise kann keine Kreuzkontamination auftreten, wenn eine App vorhanden ist verweist auf andere Apps vars), dann wird die Versionsnummer der Konfiguration von der Bezeichnung übernommen, die mit dem bereitstellbaren Artefakt verbunden ist. Das Aktualisieren dieses Etiketts ist hier der Schlüssel, da es bedeutet, dass wir, wenn wir beide Produktions-Rechenzentren verloren haben, die Umgebung wieder aktivieren können, indem wir einfach die Metadaten aus unseren bereitstellbaren Artefakten lesen und alle Umgebungsvariablen in den KV-Speicher laden .

Probleme mit diesem Ansatz Entwickler haben immer und ich meine jedes Mal einen Weg gefunden, Konfigurationsänderungen in die Umgebung zu übertragen, die erhebliche Auswirkungen auf die Ausführung der Anwendung hatten. Weil es immer einfacher war, Konfigurationsänderungen zu genehmigen als Codeänderungen.

Speichern eines "Bereitstellungs" -Artefakts mit eingebetteten Variablen

Dadurch wird die genaue Version des Artefakts eng mit der Version der Konfiguration verknüpft. Wenn Sie die Konfiguration geändert haben, mussten Sie dieses Bereitstellungsartefakt neu erstellen.

Das Bereitstellungsartefakt selbst war im Wesentlichen eine Yaml-Datei, die die URL zur freigebbaren Binärdatei und die gesamte damit verbundene Konfiguration enthielt.

Die Plattform enthält Komponenten zum Lesen von Variablen und zum Auslesen in den Prozessbaum der Anwendung beim Start.

Dies war bisher viel erfolgreicher, da es ein Artefakt gibt, dessen Geschichte wir verfolgen können und das wir jedem Prüfungsausschuss vorhalten können und das sagt: "Dies ist das einzige Artefakt, das uns wichtig ist und das wir nicht betrachten müssen." Alle anderen Änderungen, nur Änderungen an dieser Sache "(dh Version der zu implementierenden Anwendung, Umgebungsvariablen eingeschlossen usw.).

Dies macht es für Entwickler nur ein wenig schwieriger, eine Logik in ihre Anwendung zu integrieren, die ihr Verhalten basierend auf Variablen ändert, sodass sie Änderungen vornehmen können, ohne entsprechende Testzyklen durchlaufen zu müssen.

Bonuspunkte

Berücksichtigen Sie Anwendungsgeheimnisse. Unsere Lösung bestand bisher darin, einen öffentlichen RSA-Schlüssel bereitzustellen, mit dem Entwicklungsteams einen erweiterten Java-Schlüsselspeicher verschlüsseln (fast jede Sprache verfügt über eine Bibliothek, in der Java-Schlüsselspeicher gelesen werden können). Dieser wird dann wie ein dritter Artefakttyp behandelt und wird auf den Server gezogen, mit unserem privaten Plattformschlüssel entschlüsselt und der Anwendung zur Laufzeit zur Verfügung gestellt.

Zugegebenermaßen ist das Management von Geheimnissen eine eigene Dose Würmer. Aber es ist wahrscheinlich eine Überlegung wert.

hvindin
quelle
2
Betreff : Anwendungsgeheimnisse, ich würde vorschlagen, einen Blick auf Vault ( vaultproject.io ) zu werfen, da es auch Teil der Hashicorp-Toolchain ist und sich ziemlich gut in Consul (und andere Tools aus dieser Box) integriert
Michael Bravo
Ich bin tatsächlich sehr vom Tresor überwältigt, wenn man bedenkt, wie großartig Hashicorp-Zeug normalerweise ist. Im Wesentlichen drei große Lücken in ihrem Produkt gegenüber dem Rest des Marktes - 1. "Geheimnisse für Geheimnisse" ist im Wesentlichen das, worauf das Modell hinausläuft. Ich bekomme Scherben oder benutze ein HSM. Aber im Grunde ist es nur der Handel mit Geheimnissen. 2. Tool-Kompatibilität Im Gegensatz zu anderen Tools werden Plugins nicht unterstützt. 3. Preis. Ich habe es nicht geglaubt, als ich der Firma sagte, dass ich dachte, Tresor sei teuer. Sie haben Produkte abgelehnt, weil sie zu billig sind, es ist durcheinander. Aber das Gewölbe war so viel, dass sie es nicht einmal in Betracht zogen.
Hvindin
Es ist erwähnenswert, dass es nur dann unerschwinglich ist, wenn Sie eine kostenpflichtige Version verwenden . Das Kernprodukt von Vault ist Open Source. Natürlich geben sie auf ihrer Website keine Preise für Pro / Enterprise-Versionen an, daher habe ich keine Ahnung, wie [un] vernünftig dies für diese Editionen sein kann.
Adrian
Hm, ich habe diese Auslassung in meinem Kommentar nicht bemerkt, obwohl meine ersten beiden Probleme mit dem Tresor immer noch bestehen. Um mich zu qualifizieren, sind dies meine Gedanken zu Vault im Vergleich zu anderen Hashicorp-Produkten, die ich alle für ziemlich gut halte. Im Vergleich zu anderen Produkten auf dem Markt ist die Ausführung einer ähnlichen Funktion wahrscheinlich gleichwertig, nur aus irgendeinem Grund viel teurer als erwartet.
Hvindin
Können Sie ein Beispiel für "Logik in ihre Anwendung einbauen, die ihr Verhalten basierend auf Variablen ändert, damit sie Änderungen vornehmen können, ohne geeignete Testzyklen zu durchlaufen"? Klingt nach etwas wirklich Üblichem, aber ich kann mir kein konkretes Beispiel vorstellen.
Kenchew
3

Wenn Ihre Umgebungen pro Kunde sind, würde ich in Ihrem speziellen Fall vorschlagen , ein Repository pro Kunde zu haben . (Im Allgemeinen handelt es sich um ein Repository pro Umgebung.) Dieses Repository verfügt über eine Standardverzeichnisstruktur für Umgebungsvariablen, ansible Variablen und Inventare sowie stark verschlüsselte Geheimnisse (Kontozugriffstoken, private Schlüssel usw.). Sie würden den Code in diese Repositorys submodulieren. Ich würde es wahrscheinlich in mehreren Repositories tun. Eine für ansible Rollen und Module, eine für Wartungs- und Bereitstellungsskripte, eine für jede wichtige Anwendung, die in den Umgebungen ausgeführt wird.

Jetzt können Sie den Code optional tatsächlich teilen oder das Submodul auf andere Weise an einem bestimmten Tag für die Freigabe anheften , um sicherzustellen, dass sich der Code, der die Umgebung des Kunden verwaltet, nur ändert, wenn er getestet und freigegeben wird.

Wenn Sie ein Artefakt-Repository verwenden , stellen Sie sicher, dass die Artefakte ordnungsgemäß versioniert sind und diese Versionen in den Umgebungsvariablen ordnungsgemäß angegeben sind.

Die Automatisierung ist wichtig, da die Umgebungsvariablen nach Möglichkeit nicht von Menschen aktualisiert, sondern von Skripten generiert werden sollten. Stellen Sie sicher, dass das Inventar pro Kunde fast keine manuellen Aktualisierungen enthält und die Entwickler nur die Code-Repositorys aktualisieren. Wenn sie Konfigurationsänderungen vornehmen möchten, sollte dies an einem der generierenden Skripte vorgenommen werden, das dann ausgeführt wird, um die Variablen zu generieren, und der Diff wird in das Kunden-Repository übernommen. Es lohnt sich, eine kontinuierliche Integration für diesen Prozess einzurichten. Ohne dies wird es irgendwann zu viele Repositorys geben, um sie zu verwalten .

Jiri Klouda
quelle
Nur ein Einwand: Geheimnisse sollten nicht in ein Versionskontroll-Repository gelangen, es sei denn, es wird strikt von der Zugriffskontrolle unterstützt. Git nicht - wer auch immer das Repository zieht, kann die Geheimnisse sehen, was ein Problem sein kann - sie sind keine Geheimnisse mehr.
Dan Cornilescu
Guter Fang. Es sind verschlüsselte Geheimnisse. Die Entschlüsselungsschlüssel sind tramsient.
Jiri Klouda