Infrastruktur als Code und TDD

11

Die Infrastruktur als Code fordert uns auf, Tools zu verwenden, die Ihre Builds automatisieren. Groß. Tools wie Ansible , Koch , Marionette , Salzstapel und andere bringen uns dazu, zu schreiben, wie die Infrastruktur aussieht, und gleichzeitig die Unterschiede zu beseitigen .

In Salt Stack werden diese Bits als Zustände bezeichnet . Wenn der Zustand nicht mit der Realität übereinstimmt, wird das Tool ihn für uns lösen. Mit anderen Worten: Wir schreiben einen Test für unsere Infrastruktur. Wenn der Test fehlschlägt, wird er vom Tool selbst behoben. Zumindest ist das die Idee.

XP lehrt uns, TDD zu verwenden, und die Frage ist, ob es auf die Infrastruktur anwendbar ist. Das Werkzeug legt nahe, dass dies der Fall ist.

Ich kann mir einige Arten von Tests vorstellen, die sehr nützlich sein können.

Wir schreiben Rauchtests, die mit dem bereitgestellten Dienst gebündelt sind, um sicherzustellen, dass der bereitgestellte Dienst durchgängig funktioniert und wie erwartet ausgeführt wird. Dies wäre ein API-Aufruf oder / und eine systemctl-Überprüfung, um sicherzustellen, dass das, was wir gerade bereitgestellt haben, funktioniert. Ein Großteil dieser Funktionen kann in denselben Zuständen behandelt werden, da Tools wie ansible Zustände haben, um sicherzustellen, dass ein Dienst ausgeführt wird.

Es gibt das Projekt Molecule , mit dem einzelne Rollen (wie ansible seine Zustände nennt) gegen Docker oder eine andere temporäre Virtualisierungs-Engine ausgeführt werden können. Dies zwingt dazu, Rollen zu entkoppeln und ermöglicht es, sie während der Arbeit isoliert vom Spielbuch auszuführen. Tests ermöglichen meistens das Verspotten der Variablen, mit denen die Rolle arbeiten soll. Andere Beispiele scheinen jedoch eine Verdoppelung der Ansible-Engine zu sein (behaupten, eine Datei gehört einem Benutzer ...).

Das Tech-Radar von ThoughtWorks lobt derzeit Tools wie inspec , serverspec oder goss für die Überprüfung, ob der Server die Spezifikation erfüllt. Aber wir schreiben eine Spezifikation, nicht wahr?

Gibt es also einen Grund, die Infrastruktur weiter zu testen, wenn wir die Infrastruktur in Zuständen / Rollen beschreiben? Ich könnte vermuten, dass dies in größeren Organisationen, in denen ein Team die Spezifikation bereitstellt und das andere folgt, notwendiger wird, oder wenn es eine große Anzahl von Rollen gibt, möchten Sie vielleicht eine Teilmenge davon ausführen und einen Geschwindigkeitsvorteil aus Tests ziehen? Ich habe Mühe zu verstehen, warum Sie einen Test schreiben würden, wenn Sie eine Rolle / einen Status für dieselbe Frage im Auge haben könnten.

JackLeo
quelle

Antworten:

6

Kurz gesagt, ich sehe zwei Kategorien von Tests für Ihre Infrastruktur: 1) Hat sie alles, was Sie zum Ausführen Ihrer Anwendung benötigen, und 2) Hat sie keine überflüssigen Dinge?

In erster Linie können Sie die Testsuite Ihrer eigentlichen Software als eine Art "Metatest" für Ihre Infrastruktur behandeln. Solange Sie die Infrastruktur für jeden Testlauf von Grund auf neu erstellen und die Testsuite vollständig auf dieser Infrastruktur ausgeführt wird (dh keine externen Dienste verwendet), bedeutet die Tatsache, dass die gesamte Suite grün ist, dass auch Ihre kodifizierte Infrastruktur ausreicht .

Zweitens können Sie insbesondere aus Sicherheitsgründen Tests für Ihre Infrastruktur schreiben. Wenn ein Teil Ihrer Infrastruktur eine VM unter Linux ist, können Sie einen Test schreiben, der einen Port-Scan für diese VM durchführt, um sicherzustellen, dass keine unbeabsichtigten Ports geöffnet sind, die möglicherweise durch einen unbeabsichtigten apt-get installNebeneffekt installiert wurden . Sie können auch Tests schreiben, die prüfen, ob unerwartete Dateien nach Abschluss Ihrer ordnungsgemäßen Testsuite geändert wurden. Sie können auch die psAusgaben Ihrer VMs oder Docker-Container auf unerwartete Prozesse und dergleichen überprüfen, Whitelists usw. erstellen und so automatisch benachrichtigt werden, wenn ein Paket eines Drittanbieters bei einem Upgrade nicht dokumentiert (oder unbemerkt) geändert wurde.

Diese zweite Art von Tests ähnelt in gewisser Weise dem, was Sie ohnehin in einer klassischen Ops-Umgebung tun würden, dh Sie härten Ihre Server ab und suchen nach Eindringlingen, um vollständige Ressourcen und dergleichen zu vermeiden.

AnoE
quelle
Nach einiger Zeit ist dies genau die Haltung, die ich eingenommen habe. Teile, die von ansible ausgeführt werden, werden nicht von sich aus getestet, aber die Nebenwirkungen dieser Aktionen werden mit getestet goss. So wird beispielsweise RPM installiert (ansible) und dann getestet, ob die erwartete Standarddatei eingerichtet ist oder der Dienst ausgeführt wird und auf einen bestimmten Port wartet. Ich möchte ein solches Problem nicht automatisch beheben, sondern benachrichtigt werden und den Fortschritt stoppen. Sicher, Ansible kann das System auch für Sie testen. Sie müssen nur explizit darauf goss
eingehen
1

IMHO ist es ziemlich redundant, TDD-Tests für Elemente zu schreiben, die vollständig von der IaaC-Statusspezifikation abgedeckt sind. Dies impliziert, dass die Wirksamkeit des IaaC fraglich ist - warum sollten Sie es verwenden, wenn ja?

Wenn Sie es von einem anderen potenziellen IaaC aus betrachten (wenn / wenn es richtig gemacht wird), sind bereits getestete Funktionen enthalten, die als zuverlässig funktionieren. Was es attraktiv macht und was das Schreiben von TDD-Matching-Tests überflüssig macht.

Beispielsweise beinhaltet eine IaaC-Konfiguration, die ein System mit installiertem SSH angibt, bereits eine zuverlässige Überprüfung der korrekten Installation von SSH und, falls nicht, Mechanismen für die ordnungsgemäße Installation. Dies macht einen TDD-Test zur Überprüfung, ob SSH redundant installiert ist. Wenn Ihre IaaC-Konfiguration auch angibt, dass sshd gestartet und an einem bestimmten Port abgehört werden soll, sind TDD-Tests für sshd, die ausgeführt werden und den jeweiligen Port abhören, ebenfalls redundant.

Beachten Sie, dass meine Antwort nicht auf TDD oder andere Testarten abzielt, die prüfen, ob Ihre IaaC-Konfiguration insgesamt einem bestimmten Zweck entspricht. Dies bleibt gültig und kann bei TDD-, CI- oder ähnlichen Überprüfungen während der Entwicklung dieser IaaC-Spezifikation verwendet werden. Ich glaube, dass die Antwort von @ AnoE in diesem Fall anwendbar ist.

Dan Cornilescu
quelle
Wenden Sie dasselbe Denken an, um sicherzustellen, dass SSH (oder was auch immer) an einem bestimmten benutzerdefinierten Port aktiviert ist, der aus einer externen Konfigurationsdatei analysiert wird? Das ruht nicht auf getesteten Einheiten, das ist neuartige Logik.
Jon Lauridsen
1
Es sollte Teil von IaaC sein, wenn es dies unterstützt. Wenn nicht, dann trifft diese Diskussion nicht wirklich zu. Ja, dies könnte dazu führen, wie viel Material von IaaC abgedeckt werden kann, aber das ist eine andere Diskussion.
Dan Cornilescu
1
Ich gehe auch davon aus, dass wir uns nicht in einem Kontext befinden, in dem redundante Überprüfungen erforderlich sind. In einigen Fällen sind redundante Überprüfungen auf völlig anderen Codepfaden oder sogar in der Infrastruktur erforderlich.
Dan Cornilescu
1

Es sieht so aus, als ob jeder hier davon ausgeht, dass ein IAC-Tool immer wie erwartet ausgeführt wird, aber ich kann (aus eigener Erfahrung) feststellen, dass dies nicht immer der Fall ist, da sonst ein Komponententest tatsächlich nutzlos wäre.

Ich erinnere mich an ein Bild mit der Aufschrift "Ansible Playbook lief, alles ist in Ordnung" mit einem brennenden Gebäude im Hintergrund ...

Das Ausführen eines deklarativen Status und das Befinden des Servers in diesem tatsächlich deklarierten Status unterscheiden sich zumindest aus meiner Sicht und Erfahrung.

Eine breite und heterogene Umgebung, die über mehrere DC verteilt ist und über ein öffentliches Netzwerk usw. erreichbar ist. Es gibt mehrere Gründe, aus denen ein Status weder ganz noch teilweise angewendet werden kann.

Aus all diesen Gründen gibt es Raum für Unit-Tests, die es ermöglichen, einen Snapshot des tatsächlichen Serverstatus zu erhalten, der wiederum vom Zielstatus abweichen kann.

Ich würde also sagen, dass Unit-Tests auch in einer von IAC verwalteten Umgebung nützlich sind.

BEARBEITEN

Was ist mit der Nicht-Regressionsseite des Entwicklungszweigs der IaC-Codebasis? Sie würden also Änderungen an Ihrem Code im Dev-Zweig vornehmen und ihn mit dem Prod-Zweig zusammenführen, in der Hoffnung, nicht alles zu beschädigen? Unit-Tests sind so wertvoll und normalerweise einfach zu implementieren. Ich verstehe nicht, warum man ohne diese Funktion codieren würde.

Referenz (auf Französisch Entschuldigung): https://fr.slideshare.net/logilab/testinfra-pyconfr-2017

Seebrücke
quelle
1
Das wäre zumindest höflich, wenn Sie einen Kommentar mit einer Abwärtsabstimmung hinzufügen würden, denken Sie nicht an einen Abwärtswähler? Besonders bei solchen Fragen, bei denen die Debatte sehr informativ oder sogar konstruktiv sein könnte.
Pier
Ich gehe davon aus, dass der Ton Ihrer Antwort, der für alle, die mit dieser Frage interagiert haben, ziemlich aggressiv ist, zusätzlich zu der Tatsache, dass Sie keinen Hinweis aus Ihrem eigenen Beispiel geben oder eine beobachtete Fehlfunktion beschreiben, der Grund für den Downvoter war. Am Ende sagen Sie schließlich dasselbe wie in anderen Antworten: Führen Sie Rauchtests in Ihrem Bereitstellungssystem durch, um sicherzustellen, dass das System in Ordnung ist. Dies geschieht bei den meisten Systemen durch einen Ausfall, wenn sie das System nicht im gewünschten Zustand konvergieren können. In Bezug auf Ihre Bearbeitung erfolgt die Zusammenführung normalerweise nach der Bereitstellung für die Bereitstellung und Sicherstellung, dass die
Rauchtests
Ich wollte definitiv nicht aggressiv sein, ich benutze hier nicht meine natürliche Sprache (das ist offensichtlich, denke ich :)).
Pier
Wir können es im DevOps Chat diskutieren, wenn Sie es wünschen. Ich glaube, ich habe diese oder eine ähnliche Präsentation vor einigen Jahren bei einem Devoxx-Event gesehen. Ich bin etwas anderer Meinung als dieser Unit-Test, das sind eher Funktionstests.
Tensibai
Jemand aus meinem Entwicklerteam sagte mir, dass dies kein Komponententest sei. Ich bin kein Entwickler, daher kann ich mich irren, wenn ich diesen Komponententest definitiv anrufe
Pier
1

Nach meiner Erfahrung sind "Hauptlaufzeitabhängigkeiten" einer der Hauptunterschiede zwischen Dev und Ops. Die Installation von Paketen hängt stark von Repositorys, Netzwerken oder gültigen Schlüsseln ab oder beispielsweise von der Instanziierung eines neuen Cloud-Servers - dies hängt von den Ressourcen Ihres Anbieters ab.

In Bezug auf die Serverbereitstellung ist Ihr Image die meiste Zeit gültig, manchmal jedoch nicht, selbst wenn Sie Ihren Bereitstellungscode nicht geändert haben. Daher denke ich, dass das Testen für die Bereitstellung von Arbeitsbildern wirklich wichtig ist.

Wenn Sie über einzelne Server hinausgehen, wird es noch schlimmer ... wie werden Sie die Erreichbarkeit in ganzen Netzwerkeinstellungen testen? Einschließlich DNS-Auflösung, Routing und Firewall? Selbst wenn die API Ihres IaaC-Anbieters wie erwartet funktioniert (ich habe in diesem Bereich Probleme mit dem Kabel festgestellt), gefällt mir TDD in diesem Fall sehr gut.

Da ich in diesem Bereich keine Testtools gefunden habe, haben wir in unserer Freizeit eines geschrieben: https://github.com/DomainDrivenArchitecture/dda-serverspec-crate

Ich denke, TDD ist wirklich wichtig in der DevOps-Welt!

jerger
quelle