Infrastructure as Code ist zu einem der wichtigsten Themen angewachsen mit denen sich Admins und ganze IT Abteilungen beschäftigen. Wie immer wenn es um Code geht, spielt die Qualität von diesem eine wichtige Rolle. Wenn man seine Chef Cookbooks nicht gerade nur für sich selbst schreibt, sondern gern auch veröffentlichen möchte, gehört Qualität zum guten Ton. Eines der Qualitätsmerkmale ist die Anwendbarkeit des Cookbooks auf verschiedene Betriebssysteme und Versionen. Hier beginnt auch schon die Schwierigkeit: Oft wird ein Cookbook für das System geschrieben das man selbst verwendet, schlicht, weil man andere Systeme ja nicht zum Testen hat. Sicherlich ist die Zeit ein wichtiger Faktor dabei, es hat aber auch kaum jemand Lust dazu sich mit der Installation von mehreren VMs zu beschäftigen. Um richtig testen zu können, müssen diese ja auch regelmäßig zurückgesetzt werden. Abhilfe schafft da das Chef Development Kit (ChefDK).
ChefDK
Im Development Kit sind alle Tools enthalten die man braucht zum Cookbooks zu entwickeln, testen und maintainen. Es ist zudem für alle großen Betriebssysteme verfügbar. Mit dem Commandline tool chef kann man die ersten Schritte gehen: Cookbook generieren, templates anlegen etc. Auch mit dem zentralen Server kann man kommunizieren, etwa um Cookbooks zu installieren. Ein Chef Client ist im Kit auch enthalten, mit ihm lassen sich Cookbooks direkt ausführen. Das Chef Ökosystem bietet relativ viel um Cookbooks zu testen, das Wichtigste ist im ChefDK mit drin:

TestKitchen
Nun also zurück zum Problem mit dem testen von verschiednen Betriebssystemen und deren Versionen. TestKitchen zielt genau darauf ab, dieses Problem zu lösen. In einer Yaml Datei (.kitchen.yml) wird eine Testmatrix angelegt die festlegt, was genau getestet werden soll. Dazu gehören die Betriebsysteme, deren Versionen und eine oder mehrere Suites die auf diese angewendet werden sollen. Suites bestehen aus einer Liste von Recipes die ausgeführt werden. Dazugehörige Attribute können ebenfalls gesetzt werden. Beispielhaft sieht das dann so aus:

---
driver:
  name: vagrant
provisioner:
  name: chef_zero
platforms:
  - name: ubuntu-16.04
  - name: centos-7.2
  - name: windows-2012r2
suites:
  - name: icinga2server
  run_list:
    - recipe[icinga2::server]
  attributes:
    icinga2:
      version: '2.4.10-1'

Mit dem CLI Kommando kitchen kann das Cookbook jetzt auf den aufgelisteten Plattformen ausgeführt werden. Voraussetzung in diesem Beispiel ist, dass Vagrant installiert ist. Auch andere Driver können verwendet werden, Beispiele dafür wären Docker, HyperV oder OpenNebula. Eine gesamte liste findet man in der Dokumentation.

kitchen test

Das Kommando führt ein mal den gesamten Ablauf durch: VMs erstellen, Cookbook ausführen, Zustand prüfen und VMs wieder zerstören. Für jede Kombination zwischen Plattform und Suite werden mithilfe von Vagrant virtuelle Maschinen erstellt. Die dazugehörigen Boxen werden Standardmäßig von Bento angezogen. Beim ausführen sollte man aber vorsichtig sein, je nachdem wie viele Tests und Plattformen man aufgelistet hat, kann das zu relativ vielen VMs führen, was dann gerne auch mal dazu führt, dass das eigene System lahmgelegt wird.
Um das Problem zu umgehen können einzelne Instanzen erstellt werden, indem man genau angibt welche Kombination man testen möchte:

kitchen setup server-ubuntu-1604

Dieses Kommando wird eine VM mit Ubuntu 16.04 erzeugen, einen Chef Client auf dieser installieren und das Cookbook ausführen. Im Idealfall steht dann eine VM auf dem das Cookbook erfolgreich ausgeführt wurde. Man kann sich auf dieser dann auch einloggen, um ggf. manuell zu prüfen ob alles glatt gelaufen ist:

kitchen login icinga2server-ubuntu-1604

Eine Liste aller Instanzen bekommt man mit kitchen list
Zu diesem Zeitpunkt hat man zumindest die Gewissheit, dass das besagte Cookbook generell lauffähig ist und keine Fehler wirft. Ob aber tatsächlich der gewünschte Zustand erreicht ist, ist noch unklar. In Kombination mit TestKitchen lässt sich ein Zustand am besten mit ServerSpec ermitteln.
ServerSpec
Mit ServerSpec werden RSpec Tests geschrieben die den tatsächlichen Zustand eines hosts prüfen. Es wird nicht nur in Kombination mit Chef verwendet, sondern auch mit den meisten anderen Configuration Management Tools.
TestKitchen erwartet die ServerSpec Tests im Verzeichnis test/integration. Jede Suite erhält ihr eigenes Verzeichnis in dem die entsprechenden Dateien liegen in denen beschrieben ist was geprüft werden soll:

test
`-- integration
|-- icinga2server
| `-- serverspec
| |-- icinga2server_spec.rb

Beispielhaft könnte eine icinga2server_spec.rb folgenden Inhalt haben:

require 'serverspec'
require 'pathname'
set :backend, :exec
set :path, '/bin:/usr/local/bin:$PATH'
describe package(“icinga2”) do
  it { should be_installed }
end
describe service('icinga2') do
  it { should be_running }
end

Dabei wird geprüft ob auf dem System das Paket icinga2 tatsächlich installiert ist und ob der Service icinga2 läuft. Ausgedrückt werden Tests in einer relativ einfach verständlichen “Sprache”, da Begriffe und Aufbau stark an die menschliche Sprache angelehnt sind.
Aus den vorherigen Schritten sollte mindestens schon eine VM bereit stehen auf der die ServerSpec tests jetzt angewendet werden können:

kitchen verify icinga2server-ubuntu-1604

Im besten Fall ist die Ausgabe positiv

bsheqa@blerims-mbp ~/git/github/chef-icinga2 (feature/testkitchen-12286) $ kitchen verify client-ubuntu-1404
-----> Starting Kitchen (v1.10.2)
-----> Verifying ...
Preparing files for transfer
[…]
Package "icinga2"
should be installed
Service "icinga2"
should be running
Finished in 0.14585 seconds (files took 0.36682 seconds to load)
2 examples, 0 failures
Finished verifying (0m2.89s)

Mit diesem gesamten Workflow nimmt TestKitchen einem sehr viel Arbeit ab, die man sonst verwenden müsste, um virtuelle Maschinen zu pflegen und nachzusehen, ob alles so angewendet wurde, wie es im Cookbook beschrieben ist. Integration Tests selbst helfen dabei ein Gefühl dafür zu bekommen, wie sich das Cookbook als Ganzes unter verschiedenen Umgebungen mit unterschiedlichen Attributen verhält. Mit entsprechenden ServerSpec Tests gewinnt man endgültig die Sicherheit, das alles wirklich so funktioniert, wie es soll.

Blerim Sheqa
Blerim Sheqa
Product Manager

Blerim ist seit 2013 bei NETWAYS und seitdem schon viel in der Firma rum gekommen. Neben dem Support und diversen internen Projekten hat er auch im Team Infrastruktur tatkräftig mitgewirkt. Hin und wieder lässt er sich auch den ein oder anderen Consulting Termin nicht entgehen. Mittlerweile kümmert sich Blerim hauptsächlich im Icinga Umfeld um die technischen Partner und deren Integrationen in Verbindung mit Icinga 2.