Test-driven development mit Chef & Vagrant

Wenn es darum geht, auch komplexe Infrastrukturen automatisiert bereitzustellen und zu konfigurieren, ist Chef ein mächtiges Werkzeug. Getreu dem Infrastructure as Code (IaC)-Gedanken bietet es mehr als nur klassisches Configuration Management. Chef kann dazu verwendet werden, um manuelle Verfahren durch schnellere sowie mess- und wiederholbare Automatismen zu ersetzen. Bei der Entwicklung solcher Automatismen kommt häufig Vagrant zum Einsatz, um schnell temporäre VM-Instanzen unabhängig vom Hypervisor automatisiert bereitzustellen.

Was genau test-driven development (TDD) in diesem Kontext bedeutet und wie sich die erwähnten Tools hier sinnvoll benutzen lassen, wird nachfolgend beschrieben.

Aufbau und Grundlagen

Um die Theorie besser verstehen zu können, wird zunächst ein Beispiel-Szenario benannt:

In diesem Szenario soll die Bereitstellung neuer Webserver vollständig automatisiert werden. Im Wesentlichen geht es um die folgenden Teilschritte:

  • Bereitstellung einer neuen CentOS-VM
  • Installation des Apache-Webservers
  • Konfiguration und Starten des Dienstes
  • Hinterlegen von Inhalten

Infrastructure-as-Code

Zugegebenermaßen erscheinen die oben genannten Teilschritte trivial – man könnte sie auch in Form eines Skriptes automatisieren. Was hierbei aber eindeutig zu kurz käme, wären die Faktoren Versionierung, Messbarkeit und Reproduzierbarkeit.

Daher die Annahme, dass 500 Webserver sukzessive über ein Skript bereitgestellt werden. Nun gibt es Änderungen in der Software-Auswahl und neue Systeme werden mit zusätzlichen Software-Paketen betankt. Die alten Systeme sind hiervon nicht betroffen und es muss ein neuer Mechanismus gefunden werden, auch diese zu aktualisieren. Klassische Skripte werden sequentiell abgearbeitet, potentielle Fehler müssen von vornherein bedacht werden, um Ausnahmefälle zu definieren. In puncto Messbarkeit ist ein klassisches Skript ebenfalls deutlich benachteiligt, da es erstmal einfach alle Instruktionen erneut ausführt (in diesem Beispiel würde ein Webserver möglicherweise neuinstalliert werden) anstatt Kontext-bezogen relevante Aktionen wiederholt.

Der Sinn hinter IaC ist es, Infrastruktur-Ressourcen über maschinenlesbare Dateien zu definieren. Die Konfiguration und Verwaltung dieser Ressourcen kann dann von intelligenten Software-Lösungen übernommen werden. Durch den Einsatz von Versionen und Test-Katalogen können so auch komplexe Infrastruktur-Szenarien automatisiert bereitgestellt werden. Da die gesamte Infrastruktur als Code definiert ist, lassen sich (geprüfte) vorherige Versionen leicht wiederherstellen.

Hier bedient sich IaC in der Software-Entwicklung erprobten Techniken, wie beispielsweise git zur Versionsverwaltung oder test-driven development.

Abbildung 1: Infrastructure as Code

Test-driven development

Test-driven development, oder testgetriebene Entwicklung, ist eine Methode, die häufig bei der agilen Software-Entwicklung zum Einsatz kommt, sich zunehmend aber auch bei Infrastruktur-Themen großer Beliebtheit erfreut. Bei der Software-Entwicklung ist es unabdingbar, entwickelten Code anhand definierter Tests auf Funktionsfähigkeit und Erfüllung notwendiger Kriterien zu überprüfen.

Beim test-driven development werden die Tests konsequent vor der Implementation des Codes definiert, während bei der Wasserfall-Methode die Tests während bzw. nach der Entwicklung definiert werden. Durch die sehr frühe Test-Definition wird verhindert, dass Funktionalität nicht implementiert oder Testkriterien nachträglich reduziert werden, um das Projektziel zu erreichen. Darüber hinaus ist ausgeschlossen, dass Tests für entwickelte Funktionalität vergessen werden.

Ein wichtiges Merkmal ist auch die kontinuierliche Überprüfung und Verbesserung von Tests und Codes. Während in einer ersten Iteration grundgelegene Tests und Code hinterlegt werden, beinhalten weitere Iterationen Optimierungen und zusätzliche Funktionalitäten.

Infrastruktur-Deployments profitieren von dieser Vorgehensweise: durch klar definierte Soll-Zustände ist sichergestellt, dass zu entwickelnde Automatismen erst dann als vollständig gelten, wenn alle Kriterien erfüllt sind. Durch die Tests lassen sich auch bestehende Systeme überprüfen und im Zweifelsfall korrigieren – beispielsweise nach einer Iteration, die neue Funktionalität beinhaltet. Vor allem großen Systemlandschaften kommt das zugute. Während kleinere Umgebungen mit wenigen Servern manuell noch gut zu überblicken sind, ist das Vorhaben bei mehreren hunderten Servern unmöglich.

Abbildung 2: Test-driven development

Infrastruktur-Deployments profitieren von dieser Vorgehensweise: durch klar definierte Soll-Zustände ist sichergestellt, dass zu entwickelnde Automatismen erst dann als vollständig gelten, wenn alle Kriterien erfüllt sind. Durch die Tests lassen sich auch bestehende Systeme überprüfen und im Zweifelsfall korrigieren – beispielsweise nach einer Iteration, die neue Funktionalität beinhaltet. Vor allem großen Systemlandschaften kommt das zugute. Während kleinere Umgebungen mit wenigen Servern manuell noch gut zu überblicken sind, ist das Vorhaben bei mehreren hunderten Servern unmöglich. (…)

Sie wollen wissen, wie es weitergeht? Klicken Sie hier, um den ganzen Artikel auf dem Blog cstan.io nachlesen zu können.