Infrastructure as Code(2): Was Spannendes, was zum Spielen und Schokolade

Im ersten Teil dieser Serie hatte ich kurz erläutert, worum es beim Thema Infrastructure as Coder unter anderem geht. Heute will ich einmal darüber reden, warum man sich darum bemühen sollte - bzw. ob man sich darum bemühen sollte.

Als Aufhänger soll mir eine Puppet-Klasse (ich hinterlege Tools, die ich schonmal genannt habe, jetzt nicht jedes Mal mit Links) dienen, die ich letzte Woche schreiben durfte. Hintergrund ist, daß unsere Applikation einen Caching-Layer bekommen soll. Wie in vielen anderen Firmen auch fiel bei uns die Wahl des Produkts auf memcached. Dieser hat viele Vorteile, z.B. daß er einfach ist, und schnell. Ein spezieller Nachteil in unserem Setup war das Fehlen von Authentifizierung (lange Geschichte, viele Faktoren, fragt nicht). Da wir Anwendungen für verschiedene Partner betreiben, war uns irgendwie nicht ganz wohl dabei, das ganze komplett ohne Zugriffskontrolle umzusetzen - man stelle sich vor, zwei unterschiedliche Partner verwenden den selben Cache und sehen plötzlich Daten voneinander. Könnte ja bei einer Verkettung von unglücklichen Umständen passieren. Deswegen haben wir uns nochmal genau angeschaut, wofür das verwendet wird und wie unsere Applikation aufgebaut ist und sind zu zwei Schlußfolgerungen gekommen:

  1. Es ist unkritisch, wenn sich Applikationen, die mit der selben Datenbankinstanz sprechen, auch den selben Cache teilen.
  2. Will man Zugriffskontrolle, so muß man das auf Paketfilter-Ebene umsetzen, und den Zugriff für alle Anwendungen unter Punkt eins erlauben, für alle anderen jedoch verbieten.

Diese beiden Schlußfolgerungen sind wichtig, denn sie beschreiben eine Policy, die einzuhalten ist. Vor zehn Jahren hätte man diese Policy ungefähr so umgesetzt:

  1. Installation der memcached-Pakete auf den richtigen Servern.
  2. Überarbeiten der Konfiguration, so daß die richtige Cache-Größe, der korrekte Port etc. verwendet werden.
  3. Manuelle Inspektion der installierten Anwendungen, welche Datenbank verwendet wird. Dabei schreibt man sich, wenn man einen “Match” hat, die IP-Adresse des Servers auf.
  4. Konfiguration des Paketfilters auf den memcached-Servern.
  5. Anlegen einer lokalen Monitoring-Konfiguration, z.B. für NRPE.
  6. Einbinden der Checks in das Monitoring-System.

Fehler würde man bei dieser Prozedur tunlichst vermeiden wollen: Vergisst man auch nur eine IP freizuschalten, ist entweder das Caching wertlos (weil dann die eine Anwendung nicht mit dem Cache reden kann, es aber alle anderen tun, woraufhin man aus Konsistenzgründen den Cache deaktivieren müsste) oder die Anwendung müsste den Start verweigern. Und jedes Mal, wenn man einen neuen Cache für eine neue Anwendung in Betrieb nimmt, muß man alle obigen Schritte wiederholen, und darf erneut keinen Fehler machen.

Fast Forward nach 2013:

node /cacheserver[1-8]/ {
  # add node specific roles, to make sure that other classes
  # handle this node correctly
  $node_roles = {
    memcached_server => 'yes'
  }

  # merge node and base roles
  $roles      = merge($base_roles, $node_roles)
  include basenode

  # deploy and configure memcached
  class{'memcached':
    config => {
      production_database => {
        port            => 9999,
        memory          => 16384,
        manage_firewall => true,
      },
      test_database => {
        port            => 8888,
        memory          => 2048,
      },
    }
  }
}

Und obwohl 2013 schon in Code-Form ganz gut aussieht: Mit einem ENC wie Foreman hätte man das komplett über eine graphische Web-Oberfläche erschlagen können. Schauen wir uns einmal an, was die Lösung des Jahres 2013 im Einzelnen bringt.

Der erste Aspekt ist, daß obiger Code ein Rezept ist, und dies auf zwei Ebenen: Die obige Code-Definition beschreibt exakt, wie ein gegebener Server aussehen soll (in unserem Beispiel ein Basis-Betriebssystem mit nicht weiter erläuterten Eigenschaften und eben zwei memcached-Instanzen). Hier liegt der Focus auf der Policy. Wenn man sich nun den Code, der obige Definition möglich macht, ansieht, dann sieht man, welche Eigenschaften erfüllt sein müssen, um dieser Policy genüge zu tun. Ein neuer Kollege kann sich den Code durchlesen und wird schnell wissen, was es eigentlich zu beachten gibt bei unserer Caching-Infrastruktur. Und damit bringt 2013 uns “was Spannendes”.

Der zweite Aspekt wäre der der Wiederholbarkeit: Egal, ob ich einen Cache-Server betreibe oder hundert und egal, für wie viele Datenbanken der Cache zuständig sein soll, der oben genannte Code wird immer genau den erwünschten Zustand herbei führen. Eine neue Anwendung wird installiert? Nach spätestens einem Puppet-Lauf ist die Anwendung auf den Cache-Servern freigeschaltet. Man legt neue Cache-Instanzen an? Nach spätestens einem Puppet-Lauf sind sie in der Monitoring-Konfiguration vermerkt. Aus operativer Sicht ist das natürlich ein Traum: Ich kann keinen der oben genannten Schritte mehr vergessen und gleichzeitig ist es sehr komfortabel, alle diese Schritte mit ein paar einfachen Zeilen zur Konfiguration zusammen zu fassen. Das Jahr 2013 bringt mir also was “zum Spielen”.

Als dritten Aspekt muß man sehen, daß diese Art, Infrastruktur zu Verwalten, in mehrfacher Hinsicht als Dokumentation zu betrachten ist:

  1. Zum einen ist der Sollzustand des Systems dokumentiert, ohne, daß dieser in einer externen Resource wie z.B. einem Betriebshandbuch, vermerkt sein muß.
  2. Die Beschreibung der notwendigen Eigenschaften eines Caching-Servers in den einzelnen Manifesten ist gleichzeitig eine lückenlose Dokumentation: Da das Ergebnis reproduzierbar ist, kann offensichtlich nichts Fehlen oder falsch sein, sonst hätte der Code niemals die Testumgebung verlassen. Wer würde sich nicht lückenlose, fehlerfreie Dokumentationen wünschen?
  3. Zu guter Letzt kann Puppet mit dem rdoc-Mechanismus aus entsprechend strukturierten Daten innerhalb der einzelnen Manifeste Dokumentation erstellen, so daß man zwei Fliegen mit einer Klappe erschlägt: Der eigene Code ist ordentlich kommentiert, und Kollegen, die ihn nur anwenden wollen, erhalten eine ansprechend gestaltete Dokumentation “frei Haus”.

Und da es sich dabei quasi um das Sahnehäubchen handelt ist es nicht falsch zu sagen, daß 2013 uns “Schokolade” bringt (womit ich dann, zugegebenermaßen mit Ach und Krach, den Bogen zum Titel dieses Postings bekommen habe). Natürlich gibt es noch andere Vorteile:

  1. Wenn der Puppet-Code versioniert ist (und das sollte er sein!), dann kann man sehr leicht Änderungen nachvollziehen.
  2. Arbeitet man mit einem Code-Review-Tool, dann hat man im Prinzip schon einen ISO20k-konformen Change-Prozess aufgebaut.
  3. Muß die Art und Weise, wie man memcached konfiguriert, einmal geändert werden, so muß man dies nur an einer zentralen Stelle tun.

Damit dürfte gerklärt sein, “warum” man sich bemühen sollte, seine Infrastruktur so zu verwalten. Bleibt der Eingang genannte Punkt des “ob”. Auch hier lautet meine Antwort “ja” - und gleichzeitig ist mir klar, daß das nicht immer umsetzbar ist. Setzt eine IT-Abteilung noch gar keine Tools für das zentrale Konfigurationsmanagement ein, so hat sie hier natürlich einen erheblich höheren Initialaufwand. Üblicherweise ist ein Merkmal dieser Situation, daß das Team als solches das Tagesbeschäft nur “gerade so” bewältigt, und oft schleichen sich in Konfigurationen Fehler ein, die erst im laufenden Betrieb entdeckt werden. In dieser Situation steht für eine größere Umstellung wie die Einführung von Chef oder Puppet einfach keine Kapazität zur Verfügung. In dieser Situation hat das Management nun genau zwei Alternativen:

  1. Weitermachen wie bisher. Dadurch erhöht sich die Technical Debt allerdings weiter. Dem System (wir erinnern uns: IaC erfordert das Betrachten der IT-Landschaft als System von Systemen) müssen irgendwann weitere Resourcen hinzugefügt werden, wobei jedoch das Law of Stretched Systems oft verhindert, daß die neu hinzugewonnenen Resourcen die Situation grundlegend ändern können.
  2. Man macht bewusst Abstriche in der Qualität des Tagesgeschäfts und akkzeptiert, daß es während einer Übergangsphase zu Verwerfungen im Betrieb kommen wird. Dieser Weg dürfte einer der am schwersten zu vermittelnden sein, denn in Ausgangssituation des Unternehmens funktioniert das operationelle Tagesgeschäft ja im Großen und Ganzen noch.

Setzt eine IT-Abteilung dagegen bereits CM-Techniken ein, so ist hier nur ein kleiner Spagat erforderlich: Die kontinuierliche Verbesserung und Pflege des zentralen Regelwerks darf nicht zum Selbstzweck werden, der die Umsetzung anderer Projekte gefährdet. Dies ist normalerweise deutlich leichter zu erreichen, sofern man darauf Wert legt, daß neue Techniken von Anfang an über das CM abgebildet (i.e. verteilt und konfiguriert) werden. Einen Wildwuchs des bestehenden CM-Regelwerks verhindert man über Reviews beim Erzeugen neuer Regeln und durch ein periodisches Review der Gesamt-Struktur. Die Vorteile sind es meiner Meinung nach auf jeden Fall wert.

Ich höre mir jetzt Schumanns “Kreisleriana” an und gönne mir dazu Pfirsich-Eistee.