Miriam Grainer, Junior IT-Consultant

Über die Autorin

Miriam Grainer ist eine Junior IT-Beraterin für Infralovers und für Commandemy. Miriam liebt es neue Technologien und Programmiersprachen zu lernen und damit zu experimentieren. Derzeit studiert sie Informationsmanagement an der FH Joanneum Graz. Twitter LinkedIn

Alle Artikel dieses Autors sehen

Development Workflow

Wenn man über die Workstation mit Chef und einer Zielplattform interagieren möchten, müssen einige Schritte unternommen werden, damit alles reibungslos funktioniert. Dies ist auch für alle relevant, die mit einer bestimmten Anwendung oder Website in Ihrer Infrastruktur interagieren möchten. Um dieses Setup schnell und einfach zu machen, schlagen wir einen einheitlichen folgenden Workflow vor.

Erstellen eines Cookbooks

Wenn man ChefDK installiert hat, ist das Erstellen eines neuen Cookbooks unkompliziert. Man navigiert einfach in das Verzeichnis, in dem die Projekte auf Workstation gespeichert sind. Dann führt man einfach diesen Befehl aus:

chef generate cookbook my_first_cookbook

Die Ausgabe dieses Befehls sieht folgendermaßen aus:

Generating cookbook my_first_cookbook
- Ensuring correct cookbook file content
- Committing cookbook files to git
- Ensuring delivery configuration
- Ensuring correct delivery build cookbook content
- Adding delivery configuration to feature branch
- Adding build cookbook to feature branch
- Merging delivery content feature branch to master

Your cookbook is ready. Type `cd my_first_cookbook` to enter it.

There are several commands you can run to get started locally developing and testing your cookbook.
Type `delivery local --help` to see a full list.

Why not start by writing a test? Tests for the default recipe are stored at:

test/smoke/default/default_test.rb

If you'd prefer to dive right in, the default recipe can be found at:

recipes/default.rb

Das Verzeichnis enthält die folgenden Verzeichnisse und Dateien:

-rw-r--r--  1 username  staff    77 16 Dez 17:43 Berksfile
-rw-r--r--  1 username  staff    65 16 Dez 17:43 README.md
-rw-r--r--  1 username  staff  1133 16 Dez 17:43 chefignore
-rw-r--r--  1 username  staff   807 16 Dez 17:43 metadata.rb
drwxr-xr-x  3 username  staff   102 16 Dez 17:43 recipes
drwxr-xr-x  4 username  staff   136 16 Dez 17:43 spec
drwxr-xr-x  3 username  staff   102 16 Dez 17:43 test

Man muss beachten, dass bereits ein git-Repository initialisiert wurde. Wenn man in das erstellte Verzeichnis navigiert, muss man lediglich ein Remote-Repository hinzufügen und kann loslegen.

Erstellen eines Remote-Repository auf dem Git-Server und hinzufügen des Remote-Endpunktes zu dem neu erstellten Cookbook auf der Workstation:

git remote add origin https://git.yourcompany.com/workspace/my_first_cookbook.git

An diesem Punkt kann man den ersten Commit durchführen:

git add .
git commit -m "initial commit"
git push origin master

Dies ist jedoch nicht das Repository, an dem man arbeiten wird. Im Moment hat man den Ausgangszustand des Cookbooks auf das Remote-Repository gepushed. Veränderungen direkt in den Master-Branch zu schieben, wird die Zusammenarbeit sehr erschweren. Daher sollte man einen Fork des Repositorys erstellen.

Alle Aktualisierungen, Änderungen oder neuen Funktionen, die man für das Cookbook durchführt, sollten in diesem Fork vorgenommen werden. Wir empfehlen außerdem, eine separate Branch für jede Änderung / Feature, die man entwickelt, zu erstellen.

Clonen eines Cookbooks

Wenn man einen Fork oder ein anderes Cookbook vom Git-Server herunterladen möchten, den man auf der lokalen Workstation haben möchten, kann man einfach git clone verwenden, um ihn herunterzuladen.

Zuerst muss man die URL des gewünschten Repositories herausfinden. Dazu geht man zum Git Server, um diese zu finden. Die URL sieht ungefähr so ​​aus:

git@git.yourcompany.com:username/my_first_cookbook.git

Metadata

Die Datei metadata.rb befindet sich im Root-Verzeichnis des Cookbooks. Sie enthält Cookbook-Informationen und Versionsnummern.

Es enthält auch alle Cookbooks, von denen das Cookbook abhängig sein kann:

name 'my_first_cookbook'
maintainer 'The Authors'
maintainer_email 'you@example.com'
license 'all_rights'
description 'Installs/Configures my_first_cookbook'
long_description 'Installs/Configures my_first_cookbook'
version '0.1.0'

depends 'nginx'

Hier möchten wir das nginx Cookbook in unserem Cookbook verwenden.

Berksfile

Das Berksfile ist der Ort, wo wir die Abhängigkeit unseres Cookbooks von anderen Cookbooks verwalten. Es befindet sich in der Wurzel des Cookbooks und heißt Berkfile ohne Dateityperweiterung.

Das einfachste Berksfile sieht so aus:

source 'https://supermarket.chef.io'

metadata

Dies teilt dem Berksfile einfach mit, dass alle Abhängigkeiten, die in der Metadatendatei aufgeführt sind, von https: //supermarket.chef.io abgerufen werden.

Man sollte immer mindestens dieses Standard-Berkfile haben, da Test-Tools davon abhängen werden.

Es ist auch möglich, eine bestimmte Quelle für eine Cookbook-Dependency zu definieren. Vielleicht möchte man das nginx Cookbook, das wir in metadata.rb gesehen haben, direkt aus einem Git Repository anstatt aus dem Supermarkt laden:

source 'https://supermarket.chef.io'

metadata

cookbook 'nginx', git: 'https://github.com/phlipper/chef-nginx.git'

Gute Cookbooks schreiben

Linting

Wann immer man an dem Punkt ist, an dem man Änderungen festgeschrieben hat, sollte man sicher stellen, dass man die Linting-Tools ausführt.

  • Foodcritic
  • Rubocop

Um mit Foodrcitic zu linten, führt man diesen Befehl aus:

foodcritic .

Dadurch erhält man eine Liste der Verstöße, die die Best Practices von Chef berücksichtigen:

FC002: Avoid string interpolation where not required: ./recipes/default.rb:62
FC002: Avoid string interpolation where not required: ./recipes/default.rb:63
FC002: Avoid string interpolation where not required: ./recipes/default.rb:71
FC033: Missing template: ./recipes/default.rb:91

Um den Ruby-Code-Stil selbst zu optimieren, führt man Rubocop aus:

rubocop .

Wenn man möchte, dass Rubocop die gefundenen Verstöße automatisch erkennt, führt man Rubocop mit dem Flag a aus:

rubocop . -a

Die Ausgabe, wenn Verstöße gefunden werden, kann in etwa so aussehen:

config/routes.rb:37:23: C: Prefer single-quoted strings when you don't need string interpolation or special symbols.
    :confirmations => "confirmations",
                      ^^^^^^^^^^^^^^^

spec/models/guardian_spec.rb:20:33: C: Use the new Ruby 1.9 hash syntax.
    guardian1 = Guardian.create(:email => "mymail@company.com", :firstname => "Bob", :lastname => "Smith")
                               ^^^^^^^^^                  

Test-Kitchen

Wie oben erklärt, hilft Test-Kitchen dabei, das Testen von Cookbooks zu vereinfachen. Alle Tests befinden sich im Verzeichnis test des Cookbooks. Wenn man die Datei .kitchen.yml entsprechend der gewünschten Zielplattform einrichtet, kann man sie mit folgendem Befehl überprüfen:

$ kitchen list

Instance             Driver     Provisioner  Verifier  Transport  Last Action
default-ubuntu-1204  Vagrant    ChefZero     Busser    Ssh        <Not Created>

Eine Test-Kitchen Instanz ist eine paarweise Kombination aus einer Suite und einer Platform, wie in der .kitchen.yml-Datei angegeben. Es hat die einzige Instanz automatisch benannt, indem der suite-Namen (“default”) und der platform-Namen (“ubuntu-12.04”) kombiniert wurden und für DNS- und Hostnamen-Datensätze sicher ist. In diesem Fall verwenden wir Vagrant als Treiber.

Wie man sehen kann, ist sie derzeit ____. Erstellen wir also die tatsächliche VM, die wir zum Testen verwenden möchten:

kitchen create

Wenn wir uns wieder kitchen list ansehen, können wir jetzt sehen, dass sie erstellt ist:

Instance             Driver   Provisioner  Last Action
default-ubuntu-1204  Vagrant  ChefZero     Created

Dies erstellt nur eine leere Ubuntu 14.04 VM. Um das Cookbook auf der Maschine zu starten, geht man in das Verzeichnis des Cookbooks und tippt folgendes ein:

kitchen converge

Chef wird auf der Maschine installiert und das Cookbook wird ebenfalls hochgeladen. Danach führt Chef die Run-Liste in der Datei . Kitchen.yml aus.

Man kann den Chef in der Konsole laufen sehen. Abhängig vom Cookbook kann dies ein paar Minuten dauern.

Wenn wir uns wieder die kitchen list ansehen, sehen wir, dass die Instanz jetzt Converged ist:

Instance             Driver   Provisioner  Last Action
default-ubuntu-1204  Vagrant  ChefZero     Converged

Bis jetzt ist dies eine gute Möglichkeit, unser Cookbook für eine Instanz bereitzustellen. Wenn wir sehen wollen, ob alles korrekt installiert wurde:

kitchen login

Manuell ist jedoch nicht die Art, wie wir Dinge tun wollen. Wir möchten, dass Test-Kitchen nicht nur das Cookbook bereitstellt, sondern auch einige Tests durchführt! InSpec wird uns das Werkzeug dazu geben.

Wenn die Instanz nicht mehr benötigt wird, z.B. auf AWS läuft und Kosten generiert, können Sie sie zerstören, indem Sie Folgendes ausführen: kitchen destroy.

Manuell Cookbooks mit Berkshelf uploaden

Wenn das Cookbook gelinted, getestet und mit der richtigen Versionsnummer versehen ist, ist es an der Zeit, es auf den Chef-Server hochzuladen.

Wir haben Berkshelf als Tool eingeführt, um dies zu erledigen.

Erstes Mal uploaden

Wenn dieses Cookbook nie hochgeladen wurde, kann man die folgenden Befehle ausführen, um alle Dependency-Cookbooks zu installieren und dann auf den Chef-Server hochzuladen:

Dazu führt man diesen Befehl im Verzeichnis des Cookbooks aus:

$ berks install

Resolving cookbook dependencies...
Fetching 'my_first_cookbook' from source at .
Fetching cookbook index from https://supermarket.chef.io...
Installing my_first_cookbook (0.2.0) from source at .

Um es hochzuladen, führt man diesen Befehl aus:

$ berks upload

Uploading my_first_cookbook (0.2.0) to: 'https://<CHEF-SERVER>'
Uploaded all cookbooks.

Cookbook updaten

Wenn man eine aktualisierte Version des Cookbooks auf den Chef Server hochladen möchten, wird empfohlen, berks install durch berks update zu ​​ersetzen, damit Änderungen in den Cookbook-Dependencies von Berkshelf übernommen werden können. Andernfalls wird der Status ab dem ersten Start von berks install weiterhin verwendet.

Kurz gesagt, wenn man die Cookbook-Abhängigkeiten seit dem letzten Upload aktualisiert hat, sollte man diesen Befehle ausführen, um das Cookbook auf den Chef-Server hochzuladen:

$ berks update

$ berks upload

Frozen Cookbooks

Wenn man die folgende Ausgabe vom Befehl berks upload erhaltet, ist das Cookbook frozen:

berks upload

Uploading my_first_cookbook  [0.2.0]
ERROR: Version 0.2.0 of cookbook my_first_cookbook is frozen. Use --force to override.
ERROR: Failed to upload 1 cookbook.

Der Chef-Server kann von jedem Cookbook nur eine alte Version haben. Wenn man also die Version des Cookbooks nicht aktualisiert hat, akzeptiert der Chef-Server das Hochladen nicht und wird “eingefroren”. Man kann es übergehen, indem man berks upload so ausführt:

berks upload --force

Das Erzwingen einer Überschreibung wird jedoch nicht als gute Vorgehensweise angesehen. Sie sollten nur die Versionsnummer des Cookbooks aktualisieren.

Zusammenarbeit in Cookbooks

Jetzt, da man neue Funktionen erstellt und erfolgreich getestet hat, ist es an der Zeit, sie für den Rest des Teams freizugeben. Bis jetzt sollte man alle Änderungen im persönlichen Fork des Cookbooks vorgenommen haben. Wenn alle Tests grün sind, sollte man den Status an das Remote-Repository des Forks weitergeben.

Wenn dies geschehen ist, kann man einen Merge-Request an das tatsächliche Cookbook-Repository senden, von dem man geforkt hat. Man muss sicher stellen, dass der Merge-Request einem anderen Teammitglied zugewiesen ist, um die Änderungen zu überprüfen. Dieses Teammitglied kann Feedback zu Stil, fehlenden Teilen oder einfach Feedback geben, um Fragen zu stellen. Wenn beide zustimmen, dass die neuen Änderungen in Ordnung sind, werden die Änderungen im Source-Repository zusammengeführt.

Ein erfolgreicher “Merge-Request” sollte der Auslöser für eine automatisierte Release-Pipeline sein. Zum Beispiel: Verschiedene Jenkins Jobs könnten durch die Merge-Requests ausgelöst werden.

Mehr Informationen dazu finden Sie hier im nächsten Kapitel.