Ansible

Ansible in Produktion – Splunkforwarder ausrollen

Vorwort

Wir setzen bei unserem Kunden Splunk zur Logfile-aggregierung und -auswertung ein. Auf den knapp 100 Linux- und Windowshosts läuft eine Splunk-Applikation (der Splunkforwarder); dieser liest kontinuierlich Logfiles mit und sendet sie über das Netzwerk an einen zentralen Splunk-Server (der sog. Indexer). Auf diesem werden die Logfiles gesammelt und zur leichteren Durchsuchbarkeit indiziert.

Die Links zu der Rolle im Ansible-Galaxy und Github findet ihr ganz unten.

Um die Splunkforwarder auf allen Hosts zu installieren und zu konfigurieren, gibt es mehrere Möglichkeiten:

  • Auf jeden Host einzeln die Software installieren
  • Die Installation verskripten (z.B. mit bash)
  • Einen Deploymentserver nutzen
  • Ansible nutzen

Option Eins war keine wirkliche Option und wurde von vornherein ausgeschlossen, Option Zwei wurde auch schnell fallen gelassen.

Die Wahl fiel schlussendlich auf Option Vier (sonst würde es diesen Blogeintrag nicht geben). Grund dafür, warum wir uns gegen den Deploymentserver und für Ansible entschieden haben, waren unsere fehlende Erfahrung mit dem Deploymentserver und die vorhandene mit Ansible.

Idee

Um die Splunkforwarder auszurollen haben wir eine Ansible-Rolle geschrieben, welche den Forwarder installiert und für den ersten Start vorbereitet. Um Probleme bei Updates zu vermeiden, trennen wir unsere Konfiguration von der Splunk-Standardkonfiguration. Dazu wird im Forwarder eine neue App (namens “Custom”) erstellt, in der dann alle Konfigurationen untergebracht werden. Dazu zählen unter anderem welche Logfiles gelesen werden und an welchen Indexer sie gesendet werden.

Umsetzung

Soviel zur Grobplanung, kommen wir nun zu den eigentlichen Ansible-Tasks. Zuerst wird der Splunk Universal Forwarder auf dem Client aus unseren eigenen Repositories heraus installiert. Die passende RPM-Datei findet man auf der Downloads-Seite von Splunk. Danach wird der Splunk System-User erstellt. Damit er Zugriff auf alle nötigen Logfiles bekommt, muss er in die entsprechenden Gruppen hinzugefügt werden:

Mit Hilfe der with-items-Schleife kann man Splunk einfach und kompakt zu vielen Gruppen hinzufügen. Die Direktive “ignore_errors” ist sinnvoll, wenn eine bestimmte Gruppe auf einem Host nicht existiert (z.B. mysql auf Webservern). Diese Gruppe wird dann einfach ausgelassen, der Task jedoch nicht aufgrund von Fehlern abgebrochen.

Die nächsten beiden Tasks sorgen dafür, dass die Splunk-Lizenz initial akzeptiert wird, sowie der Forwarder beim Start des Hosts mitstartet:

Der nächste Schritt ist, Splunk an ein definiertes Interface zu binden. Dies ist aus einem Sicherheitsaspekt heraus ratsam. Dazu wird die Variable frontend-ip definiert, welche die IP-Adresse des Interfaces beinhaltet. Danach wird diese Adresse in zwei Konfigurationsdateien mittels dem lineinfile-Modul eingetragen.

Danach geht es an die eigentliche Konfiguration von Splunk. Zuerst wird die Standard-Such-App von Splunk gelöscht. So haben wir volle Kontrolle darüber, was von Splunk indiziert wird. Zusätzlich wird unsere “Custom”-App gelöscht, falls sie bereits vorhanden ist. Dies sorgt dafür, dass eventuelle Fehlkonfigurationen oder alte Einstellungen gelöscht werden.

Jetzt wird die zuvor gelöschte App neu erstellt und mit Inhalt befüllt. Dazu existieren 3 Templates:

  • limits.conf
  • outputs.conf
  • inputs.conf

In der limits-Konfiguration gibt es akutell nur einen Parameter, nämlich den Datendurchsatz. Dieser ist auf 0 gestellt, so dass bei der Übertragung von Daten an den Indexer keine Bandbreitenlimitierung besteht.

In der outputs-Konfiguration wird, neben diversen Einstellungen, auch der Splunk-Indexserver angegeben. Dieser wird in der Variable splunkforwarder_server definiert.

Die inputs-Konfiguration beinhaltet den wichtigsten Teil: die zu indizierenden Logfiles. Hier wird zwischen zwei Arten von Logfiles unterschieden. Logfiles, die auf allen Hosts indiziert werden (Variable splunkforwarder_log_items), sowie Logfiles, die nur auf bestimmten Hosts indiziert werden (Variable splunkforwarder_log_items_custon). Beide Variablen sind Listen in der gleichen Form:

Eine Liste kann beliebig viele Objekte (=Logfiles) enthalten. Ein Objekt hat vier Variablen:

  • app_name: Der Name der App, sollte immer custom sein
  • source: Die zu indizierende Logfile
  • index: Der Index, in den die Daten abgelegt werden (muss vorher natürlich erstellt werden)
  • sourcetype: Der Sourcetype der zu indizierenden Daten

Die Liste splunkforwarder_log_items kann jetzt als Group-Variable genutzt werden, z.B. in der Gruppe all, damit diese Logfile auf allen Hosts indiziert wird.

Will man nun auf bestimmten Hosts zusätzliche Logfiles indizieren, die auf anderen Hosts nicht existieren, kommt die zweite Variable splunkforwarder_log_items_custom ins Spiel. Diese wird genauso genutzt wie die erste Variable, nur wird sie in den Host-Variablen oder Group-Variablen für einzelne Hosts oder Hostgruppen genutzt.

Diese beiden Listen werden dann mit einer Jinja-for-Schleife in der inputs.conf zusammengefügt und auf den Hosts ausgerollt.

Zum Schluss wird der Splunkforwarder neugestartet und man kann (hoffentlich) beobachten, wie Splunk sich mit indizierten Daten füllt.

 

Weiterführende Links

Rolle in Ansible-Galaxy: https://galaxy.ansible.com/list#/roles/3500

Rolle in Github: https://github.com/mms-segu/ansible_splunkforwarder

 

Beitragsbild: Wikimedia Commons

 

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.