Orchestrierung und Puppet
Tags: puppet, orchestration, automation, bolt
Published: 2021-08-16 07:01:49

## Was ist Orchestrierung?

Unter Orchestrierung versteht man in der IT einen Ablaufprozess, bei dem entweder auf einem System Schritte in einer bestimmten Reihenfolge ausgeführt, oder bei dem Server-übergreifende Abläufe durchgeführt werden müssen.

Ein Beispiel für einen Ablaufprozess auf einem System ist die Aktualisierung einer Applikation.
Ein solcher Ablauf kann wie folgt aussehen:

1. Stoppen des Applikationsservers
1. Installation der neuen Version der Applikations-Software
1. Ausführen von einmaligen, initialen Kommandos (z.B. Caches füllen)
1. Starten des Applikations Server auf localhost
1. Durchführen der Test Scripte zur funktionalen Überprüfung
1. Normaler Neustart des Applikationsservers

Ein Beispiel zur Orchestrierung über mehrere Systeme hinweg kann ein Applikationsupdate mit Datenbank Schema-Update sein:

1. Auf dem Applikations Server werden die oben genannten Schritte 1-5 durchgeführt
1. Auf dem Datenbank Server muss danach das Schema-Update eingespielt werden
1. Auf dem Applikations Server wird Schritt 6 ausgeführt.

## Was ist Puppet

[Puppet](https://puppet.com) ist ein Tool zum Konfigurationsmanagement, welches auf einer Client-Server-Achitektur beruht.
Auf jedem System, das mit Puppet verwaltet werden soll, muss ein Puppet Agent installiert sein.
Dieser Puppet Agent holt die Konfiguration für das eigene System vom zentralen Puppet Server.

Ein wesentliches Kennzeichen von Puppet ist "deklaratives Konfigurationsmanagement". Das bedeutet, dass man den finalen Zustand eines Systems beschreibt.
In Puppet selber sind Ablaufprozesse (Service stop, Service start) widersprüchlich und deshalb nicht möglich.

## Wie geht Orchestrierung in Puppet?

Für eine Orchestrierung im Puppet Umfeld kann [Puppet Bolt](https://puppet.com/docs/bolt/latest/bolt.html) genutzt werden.
Puppet Bolt benötigt keinen Client, sondern nutzt bestehende Zugänge (z.B. SSH oder WinRM) oder arbeitet in Kombination mit dem Puppet Messaging Client (pxp-agent) und Puppet Enterprise.

### Puppet Bolt Ablaufsteuerung mit Tasks

Die erforderlichen Abläufe ([Tasks](https://puppet.com/docs/bolt/latest/tasks.html)) können als Script (Shell, Python, Ruby, Powershell) in einem Puppet Modul im `tasks` Verzeichnis hinterlegt werden und bekommen zusätzlich eine JSON Beschreibungsdatei.

Beispiel einer Task zum Applikationsupdate (ohne Fehlerbehandlung):

    # app/tasks/update.sh
    #!/bin/bash

    # Setzen der Script Variablen
    version=$PT_version

    # Stoppen des Applikationsserver (egal ob systemd oder sysv)
    puppet resource service tomcat ensure=stopped

    # Installation der Applikation (egal, ob apt, yum oder zypper)
    puppet resource package app ensure=$version

    # Ausführen des Initialisierungs- und Tests-Scriptes
    /usr/local/bin/app_init.py
    /usr/local/bin/app_check.sh

    # Starten des Applikationsservers
    puppet resource service tomcat ensure=running

Und die dazugehörige Beschreibungsdatei:

    # app/tasks/update.json
    {
      "description": "Aktualisierung APP",
      "input_method": "environment",
      "parameters": {
        "version": {
          "description": "Zu installierende Version",
          "type": "String[1]"
        }
      }
    }

Diese Task kann nun mit Puppet Bolt auf den Zielsystemen ausgeführt werden:

    bolt task run app::update version='1.2.3' --targets <node1>, <node2> --modulepath <pfad zum Modul>

### Puppet Bolt Server Ablaufsteuerung mit Plans

Mit Tasks kann man Schritte auf einem System in Reihenfolge bringen. Wenn es um Server-übergreifende Ablaufsteuerung geht, nutzt man in Puppet Bolt [Plans](https://puppet.com/docs/bolt/latest/plans.html).

Plans können in Puppet DSL oder YAML geschrieben werden und führen Bolt Tasks, Scripte und Kommandos auf Remote Systemen aus.

Plans werden in einem Puppet Modul im `plans` Ordner hinterlegt.

Beispiel für ein Applikations-Update mit einem Datenbank Schema-Update (Puppet DSL):

    # app/plans/update.pp
    plan app::update (
      TargetSpec $appservers,
      TargetSpec $dbserver,
      String[1]  $version,
      Boolean    $update_schema=true,
    ){
      $update_result = run_task('app::update', $appservers, 'version' => $version)
      out::message($update_result)

      if $update_schema {
        $schema_result = run_task('app::schema', $dbserver, 'version' => $version)
        out::message($schema_result)
      }
    }

Für das Starten des Plans wird ebenfalls Puppet Bolt verwendet:

    bolt plan run app::update appservers='["<node1>","<node2>"] dbserver='<db>' version='1.2.3' update_schema=true

Alternativ kann der Plan auch in YAML geschrieben werden:

```
steps:
  - task: app::update
    targets:
      - node1
      - node2
    parameters:
      version: '1.2.3'
  - task: app::schema
    targets:
      - db
    parameters:
      version: '1.2.3'
      update_schema: true
```

## Zusammenfassung

Mit Puppet bekommt man die Systeme eingerichtet und konfiguriert. Der Puppet Agent stellt regelmässig sicher, dass das System so konfiguriert ist, wie es sein soll.

Mit Puppet Bolt bekommt man ein Orchestrierungswerkzeug, dass es den Systemverantwortlichen ermöglicht, Ablaufprozesse durchzuführen.