Chef Cookbooks und Kitchen

Thumbnail

AWS hat Chef als Technologiepartner. Da nicht nur AWS Chef in ihren Services wie OpsWorks oder OpsWorks Chef Automate nutzt, sondern auch wir, möchte ich eine kurze Einführung von Chef und Test-Kitchen geben.

In diesem Teil werden wir feststellen, wie schnell es geht, ein Testsystem mit den richtigen Mitteln zu erstellen. Im nächsten Teil werden wir das Ganze noch weiter verfeinern.

Chef Cookbooks und Kitchen

Warum Chef und was hat das mit AWS zu tun? Bevor wir weiter ausholen, kommen wir direkt auf den Punkt: Wir wollen alle immer wieder die selbe Software in einer gewissen Version und Konfiguration auf unseren Systemen haben, ohne ein Script auszuführen, welches dann eventuell niemand mehr lesen kann oder gar nur einmalig ausgeführt werden kann. Hier kommt Chef ins Spiel und kommt genau diesem Wunsch nach.

Chef wird schon seit 2013 im AWS Service OpsWorks eingesetzt. Damals wurde die Chef Version 11.4 eingesetzt. Heute sind wir unabhängig von Opsworks bei der Version 14.10.9.

Die Basis von Chef besteht aus sogenannten Cookbooks, welche wiederum Recipes beinhalten. In diesen wird der gewünschte Zustand definiert.

Um Cookbooks zu testen kommt “kitchen” zum Einsatz.

Kitchen

Kitchen ist ein Teil vom ChefDK, welches diverse Erweiterungen bereits von Hause aus mit liefert. Darunter befinden sich kitchen-ec2, kitchen-vagrant oder kitchen-vcenter. Die Idee hinter kitchen ist es, ein Cookbook auf einer frisch provisionierten virtuellen Maschine / EC2 Instanz auszurollen. Dazu werden sogenannte run_lists definiert, aber auch die entsprechenden Tests sollten nicht fehlen.

Generell

Wir werden gleich ein wenig tiefer in die Materie einsteigen, brauchen jedoch ein paar Dinge als Vorbereitung dafür. In den nächsten Schritten installieren wir Docker, das ChefDK und erstellen unser erstes Cookbook mit Inhalt. Im Anschluss lassen wir einen kleinen Test gegen einen frisch erstellten Dockercontainer laufen.

Also starten wir: Um unser erstes Cookbook in einer sogenannten “kitchen node” laufen zu lassen, brauchen wir ein paar Voraussetzungen, die wir erfüllen müssen:

  • Docker
  • ChefDK
  • ein Cookbook mit minimalem Inhalt (eine einfache file resource hilft uns dabei)
  • einen definierten kitchen Treiber, den wir in der .kitchen.yml definieren

Gehen wir ein wenig mehr ins Detail

Download und Installation

Docker

Geht auf die “Get Started” Seite von Docker und wählt das entsprechende Downloadpaket herunter, installiert es und überprüft, ob Docker im Hintergrund läuft.

Testen könnt Ihr das mit Hilfe des commands docker ps. Wird hier ein Fehler ausgeworfen, dann läuft Docker noch nicht.

Ist Docker installiert und funktionsfähig, haben wir bereits die Basis für die Erstellung unserer kitchen node gelegt.

ChefDK

Das ChefDK wird für alles mit Chef und kitchen benötigt. Der einfachste Weg, wie das ChefDK installiert wird, ist es herunter zu laden, aber auch homebrew bietet am Mac eine Möglichkeit dafür: Variante 1: Gehe auf downloads.chef.io und lade das entsprechende Paket herunter und installiere es Variante 2: Öffne ein Terminal und schreibe den Befehl hinein brew cask install chef/chef/chefdk

Beide Varianten installieren die derzeit aktuellste stable Version vom ChefDK. Mein bevorzugter Weg ist Variante 1, da ich immer die Version vordefinieren kann, ohne spezielle Versionsangaben in der Syntax der homebrew installationen zu nutzen. In der Vergangenheit ist es auch vorgekommen, dass homebrew mehrere Versionen hinter der aktuellsten gehangen hat.

Zusätzlich wird kitchen-docker benötigt. Dazu muss nach der Installation chef gem install kitchen-docker in Powershell oder im Terminal ausgeführt werden.

Cookbooks erstellen und eine Resource hinzufügen

Okay, wir haben das ChefDK installiert und können jetzt damit loslegen und ein Cookbook erstellen. Im Anschluss kommt der Inhalt des Recipes.

Ein Cookbook erstellen geht mit dem Befehl:

chef generate cookbook kitchen_testing

Danach gehen wir per cd kitchen_testing in das Cookbook Verzeichnis, welches soeben angelegt wurde. Dort befindet sich ein weiteres Verzeichnis namens recipes, worin sich das default.rb Recipe befindet. Dieses bearbeiten wir mit unserem bevorzugten Editor (in meinem Fall vim):

vim recipes/default.rb

Füge den folgenden Inhalt hinzu und speichere die Datei:

    file "/tmp/mykitchentest.md" do
      owner 'root'
      group 'root'
      mode '0755'
      content 'made for cooking'
    end

Kitchen

Bei der Erstellung unseres Cookbooks wurde automatisch eine .kitchen.yml in unserem Hauptverzeichnis vom Cookbook angelegt. Sie beinhaltet die gesamte Konfiguration unserer Kitchen Umgebung, die wir in den nächsten Schritten aufbauen.

    ---
    driver:
      name: vagrant
    
    provisioner:
      name: chef_zero
      always_update_cookbooks: true
    
    verifier:
      name: inspec
    
    platforms:
      - name: ubuntu-16.04
      - name: centos-7
    
    suites:
      - name: default
        run_list:
          - recipe[kitchen_test::default]
        verifier:
          inspec_tests:
            - test/integration/default
        attributes:

kitchen configuration

Lasst uns einen genaueren Blick in den driver Bereich der .kitchen.yml werfen. Der name definiert das Plugin, welches beim Ausführen von Kitchen aufgerufen wird. Die offizielle Liste aller Plugins findet ihr hier.

Da wir Docker installiert haben, wollen wir Docker auch nutzen. Ändert also dazu den name auf docker.

    ---
    driver:
      name: docker

Um zu überprüfen, ob die Konfiguration vollständig ist und auch der Treiber geladen wurde, kann der Befehl kitchen list ausgeführt werden. Er wird eine kurze Liste ausgeben:

  Instance             Driver  Provisioner  Verifier  Transport  Last Action    Last Error
  default-ubuntu-1604  Docker  ChefZero     Inspec    Ssh        <Not Created>  <None>
  default-centos-7     Docker  ChefZero     Inspec    Ssh        <Not Created>  <None>

In der Anzeige ist direkt erkenntlich, dass wir zwei Instanzen mit Docker als Treiber haben. Der Prefix “default” gibt den Namen der Suite an, die in der .kitchen.yml hinterlegt ist.

Wir wollen nur die Ubuntu Instanz erstellen. Dazu muss kitchen create ubuntu ausgeführt werden. Dieser Befehl wird den Docker Container herunterladen und erstellen. Der Clou hinter dem Befehl ist, dass dort regex angewandt wird. Wir könnten also auch anstatt “ubuntu” nur “ub” schreiben, weil dort nur eine Instanz gefunden wird.

Okay, überprüfen wir, ob wir uns in die Instanz einloggen können.

kitchen login ubuntu

Hat das geklappt, schauen wir mit ls -la /tmp, dass die Datei namens mykitchentest.md nicht vorhanden ist.

Gut, loggen wir uns wieder aus und lassen kitchen das cookbook ausführen (converge)

kitchen converge ubuntu

Wir sehen auf den ersten Blick, dass sich die Datei /tmp/mykitchentest.md verändert wird. Damit hat der converge funktioniert.

kitchen destroy entfernt alle erstellten Container, die wir vorher eventuell erstellt haben.

-> Das ist das Basiswissen und der reguläre Weg im Umgang mit kitchen. Es gibt natürlich noch viel mehr, was mit kitchen und weiteren Treibern wie kitchen-vcenter gemacht werden kann. Dazu gibt es in Zukunft weitere Beiträge, die einen tieferen Einblick verschaffen werden.


Patrick Schaumburg

Cloud Consultant and Trainer at tecRacer Consulting with a focus on Chef, AWS and DevOps.

Share