Managing your Ansible Environment with Galaxy

Ansible is known for its simplicity, lightweight footprint and flexibility to configure nearly any device in your infrastructure. Therefore it’s used in large scale environments shared between teams or departments. This leads to even bigger Ansible environments which need to be tracked or managed in version control systems like Git.

Mostly environments grow with their usage over time, in this case it can happen that all roles are managed inside one big repository. Which will eventually lead to quite messy configuration and loss of knowledge if roles are tested or work the way they supposed to work.

Ansible provides a solution which is called Galaxy, it’s basically a command line tool which keeps your environment structured, lightweight and enforces your roles to be available in a specific version.

First of all you can use the tool to download and manage roles from the Ansible Galaxy which hosts many roles written by open-source enthusiasts. 🙂


# ansible-galaxy install geerlingguy.ntp -v
Using /Users/twening/ansible.cfg as config file
 - downloading role 'ntp', owned by geerlingguy
 - downloading role from https://github.com/geerlingguy/ansible-role-ntp/archive/1.6.4.tar.gz
 - extracting geerlingguy.ntp to /Users/twening/.ansible/roles/geerlingguy.ntp
 - geerlingguy.ntp (1.6.4) was installed successfully

# ansible-galaxy list
# /Users/twening/.ansible/roles
 - geerlingguy.apache, 3.1.0
 - geerlingguy.ntp, 1.6.4
 - geerlingguy.mysql, 2.9.5

Furthermore it can handle roles from your own Git based repository. Tags, branches and commit hashes can be used to ensure it’s installed in the right version.


ansible-galaxy install git+https://github.com/Icinga/ansible-icinga2.git,v0.2.0
 - extracting ansible-icinga2 to /Users/twening/.ansible/roles/ansible-icinga2
 - ansible-icinga2 (v0.2.0) was installed successfully

It’s pretty neat but how does this help us in large environments with hundreds of roles?

The galaxy command can read requirement files, which are passed with the “-r” flag. This requirements.yml file can be a replacement for roles in the roles path and includes all managed roles of the environment.


# vim requirements.yml
- src: https://github.com/Icinga/ansible-icinga2.git
  version: v0.2.0
  name: icinga2

- src: geerlingguy.mysql
  version: 2.9.5
  name: mysql

Then run ansible-galaxy with the “–role-file” parameter and let galaxy manage all your roles.


# ansible-galaxy install -r requirements.yml
 - icinga2 (v0.2.0) is already installed, skipping.
 - downloading role 'mysql', owned by geerlingguy
 - downloading role from https://github.com/geerlingguy/ansible-role-mysql/archive/2.9.5.tar.gz
 - extracting mysql to /Users/twening/.ansible/roles/mysql
 - mysql (2.9.5) was installed successfully

In case you work with Ansible AWX, you can easily replace all your roles with this file in the roles directory and AWX will download and manage your roles directory automatically.

A example project could look like this.


awx_project/
├── example_playbook.yml
├── group_vars
├── host_vars
├── hosts
└── roles
    └── requirements.yml

In summary, in large environments try to keep your code and configuration data separated, try to maintain your roles in their own repository to avoid conflicts at the main project.

Check out our Blog for more awesome posts and if you need help with Ansible send us a message or sign up for one of our trainings!

Thilo Wening
Thilo Wening
Consultant

Thilo hat bei NETWAYS mit der Ausbildung zum Fachinformatiker, Schwerpunkt Systemadministration begonnen und unterstützt nun nach erfolgreich bestandener Prüfung tatkräftig die Kollegen im Consulting. In seiner Freizeit ist er athletisch in der Senkrechten unterwegs und stählt seine Muskeln beim Bouldern. Als richtiger Profi macht er das natürlich am liebsten in der Natur und geht nur noch in Ausnahmefällen in die Kletterhalle.

Entwicklerazubis: Jahr 1, das Projekt

Man bekommt nicht immer das, was man will… außer, man ist bei NETWAYS Azubi!

 

Mein erstes Jahr bei NETWAYS ist fast vorüber, und meine jugendlichen Ambitionen haben den Wunsch in mir erweckt, mit den beiden anderen Dev-Azubis meines Jahres, Loei und Niko, ein eigenes Projekt zu übernehmen, um unsere erlernten Fertigkeiten zu prüfen, eine Übersicht davon zu bekommen, auf welchem Stand wir alle sind, den ein oder anderen Trick voneinander aufzuschnappen und eigenverantwortlich und kooperativ ein Projekt zu vervollständigen. Und alles, was es gebraucht hat, um diesen Wunsch zu erfüllen, war diese Idee zu pitchen und klar und deutlich zu vermitteln, warum dieses Interesse besteht, und was wir uns davon erhoffen. Meine Vorgesetzten scheinen von der Idee zumindest angetan genug gewesen zu sein, dass wir drei Wochen eingeräumt bekommen haben, um uns um dieses Projekt zu kümmern. Danke, NETWAYS!

Die Aufgabe klingt einfach, hat es aber doch durchaus in sich – aus Berichten in Icinga sollen PDFs generiert werden. Die Funktionalität ist schon vorhanden – unsere Aufgabe ist es, den Benutzern mehr Features zur Verfügung zu stellen, damit man eigene Anpassungen an dem Aussehen der PDFs vornehmen kann. Das Schöne an dieser Aufgabe ist die Breite der Elemente und Bereiche, welche eine Rolle dabei spielen. Icingaweb, PHP, HTML, CSS, Google Chrome… es ist in gewisser Art und Weise eine große Reise in das Unbekannte, und natürlich können wir alle drei uns nicht sicher sein, welche Probleme und Hürden sich uns in den Weg stellen werden, und wie die zündenen Ideen kommen, die uns helfen, diese Hürden zu überwinden.

 

Boo

Much better

Und zündende Ideen gab’ es bereits! Ein Beispiel: Google Chrome baut sich aus HTML-Code die PDFs zusammen, lässt sich es aber nicht nehmen, automatisch generierte Header und Footer anzufügen, mit Seitenzahl und Datum. Das ist natürlich ein Element, welches wir gerne unter Kontrolle hätten! Der erste Hack, mit dem ich mich über diese Hürde bewegt habe, ist ein CSS-Styleelement an den übergeben HTML-Code anzufügen. Das ist in seinem momentanen Zustand natürlich noch etwas unschön gelöst, wenn einfach nur der HTML-Code um ein fest eingebautes Codeelement erweitert wird, aber wir haben einen Einstiegspunkt, einen Ansatz, mit der wir weiterbauen und -basteln können.

 

Scheue Dich vor Fragen nicht!

Auch wenn der Kerngedanke dieses Projekts natürlich daraus besteht, dass wir uns selbst beweisen, spricht natürlich Nichts dagegen, bei Fragen, die aufkommen, einen der zahlreichen Experten die NETWAYS hat zu involvieren. Was Benutzeroberflächen angeht, ist bei uns UX-Designer Florian der Ansprechpartner Nummer 1. Wir haben uns zusammengesetzt und konnten ihm live beim Bauen eines Mockups in Sketch zusehen. Eine Gelegenheit, durch die großen Augen, die wir gemacht haben, auch etwas über grundlegende Designansätze in Icingaweb zu lernen, und Grundsätze bezüglich Design. Mit diesem Wissen können wir erstmal diesen Pfad weiter selbst beschreiten, aber natürlich werden wir viel Rücksprache führen. Nur weil man bisher nicht dazu kam, sich extensive Kenntnisse in einem Bereich selbst anzueignen, heißt das nicht, dass man dieses Wissen, wenn es einem zur Verfügung steht, nicht nutzen kann. Und immer schön dran denken, selbst den Fundus an Talenten zu erweitern.

A mockup of things to come…

 

Kooperatives Kodieren

Einer der in meiner Einleitung angesprochenen Tricks, den ich einfach für neat halte, und sehr dem Spirit dieses Projektes entspricht, ist die Möglichkeit in git Co-Authoren einzutragen. Dafür muss man in der commit message einfach

 Co-authored-by: Name <e-mail>

angeben, und git verlinkt automatisch zwei Autoren für diesen commit. In diesem Fall meine beiden Kollegen bei diesem Projekt. Gute Arbeit, Jungs!

Da kann man ruhig mal klatschen! 👏

 

Willst Du uns vielleicht nächstes Jahr bei dem nächsten Entwicklungsprojekt behilflich sein? Dann raus mit Deiner Bewerbung an NETWAYS! Wir freuen uns schon auf dich!

Henrik Triem
Henrik Triem
Junior Developer

Henrik is Anwendungsentwickler in Ausbildung, verhindeter Rockstar, kaffeegetrieben und Open Source-begeistert. Zuhause lässt er es auch mal ruhiger mit Tee angehen, entspannt an Klavier oder Gitarre, erkundet neue Musik oder treibt sich mit seinen Freunden in Deutschland herum.

Migration von GitLab mit Upgrade auf EE

Wer GitLab CE produktiv im Einsatz hat und mit den zusätzlichen Features der EE Version liebäugelt, der wird sich beim Umstieg zwangsläufig mit den Migrationsschritten auseinandersetzen, sofern der GitLab Server nicht von einem Hoster betreut wird. In diesem Post zeige ich, wie der Wechsel inklusive Migration auf einen anderen Server gelingen kann und beziehe mich dabei auf die Omnibus Version basierend auf Ubuntu 18.04. Der Ablauf ist gar nicht so kompliziert. Bügelt man die EE-Version einfach über die aktuelle CE Version, dann hat man nur zwei Schritte zu beachten. Wenn man allerdings einen EE Server parallel hochzieht, um dann auf diesen zu migrieren, so kommen ein paar mehr Schritte hinzu.
Deshalb zeige ich im Folgenden wie man per Backup und Restore auch zum Ziel kommt. Die ersten Schritte sind ziemlich identisch mit dem, was GitLab vorgibt.

  1. Zuerst erstellt man sich ein Backup:
    gitlab-rake gitlab:backup:create STRATEGY=copy

    Einfach um sich den aktuellen Stand vor der Migration zu sichern.
    Hier kann nicht viel schief gehen. Man sollte aber darauf achten, dass genügend Speicherplatz unter /var/opt/gitlab/backups zur Verfügung steht. Es sollten mindestens noch zwei Drittel des Speicherplatzes frei sein. Das resultierende Tar-Archiv sollte man sich anschließend weg kopieren, da im weiteren Verlauf ein weitere Backup erstellt wird.

  2.  Nun führt man das Script von GitLab aus, das die apt-Sourcen hinzufügt und ein paar benötigte Pakete vorinstalliert:
    curl https://packages.gitlab.com/install/repositories/gitlab/gitlab-ee/script.deb.sh | sudo bash
  3. Jetzt checkt man noch kurz welche Versionsnummer von GitLab CE momentan installiert ist:
    dpkg -l |grep gitlab-ce
  4. Danach installiert man die GitLab EE Version. Dabei wird die CE Version gelöscht und eine Migration durchgeführt. Um den Versionsstand kompatibel zu halten, verwendet man die gleiche Versionsnummer wie aus dem vorherigen Schritt. Lediglich der teil ‘ce’ wird zu ‘ee’ abgeändert:
    apt-get update && sudo apt-get install gitlab-ee=12.1.6-ee.0
  5. Nun erstellt man erneut ein Backup:
    gitlab-rake gitlab:backup:create STRATEGY=copy
  6. Das neu erstellte Backup transferiert man einschließlich der Dateien /etc/gitlab/gitlab-secrets.json und /etc/gitlab/gitlab.rb auf den EE Server. Das lässt sich z.B. per scp bewerkstelligen:
    scp /var/opt/gitlab/backups/*ee_gitlab_backup.tar ziel-server:./
    scp /etc/gitlab/gitlab-secrets.json ziel-server:./
    scp /etc/gitlab/gitlab.rb ziel-server:./
  7. Auf dem Zielserver sollte man natürlich GitLab EE in der entsprechenden Version installieren. Hier hält man sich am besten an die offizielle Anleitung. Nicht vergessen bei der Installation die Versionsnummer anzugeben.
  8. Jetzt verschiebt man die Dateien die man per scp transferiert hat und setzt die Dateiberechtigungen:
    mv ~/*ee_gitlab_backup.tar /var/opt/gitlab/backups
    mv ~/gitlab-secrets.json ~/gitlab.rb /etc/gitlab/
    chown root:root /etc/gitlab/gitlab-secrets.json /etc/gitlab/gitlab.rb
    chown git:git /var/opt/gitlab/backups/*ee_gitlab_backup.tar
  9. Dann startet man den Restore:
    gitlab-rake gitlab:backup:restore

    Man quittiert die einzelnen Abfragen mit ‘yes’. Hat sich die URL für den neuen EE Server geändert, dann sollte man das in der /etc/gitlab.rb anpassen. In diesem Fall sind auch Änderungen an den GitLab Runnern vorzunehmen. Es reicht dann allerdings wenn man auf dem jeweiligen Runner in der Datei config.toml die URL in der [[runners]] Sektion anpasst, da der Token gleich bleibt.

Troubleshooting:

Es ist allerdings auch möglich, dass es zu Problemen mit den Runnern kommt. Dies zeigt sich z.B. dadurch, dass der Runner in seinen Logs 500er-Fehler beim Verbindungsversuch zum GitLab meldet. In diesem Fall sollte man zuerst versuchen den Runner neu zu registrieren. Falls die Fehler bestehen bleiben, ist es möglich, dass diese durch einen CI-Job verursacht werden, der während der Migration noch lief. So war es zumindest bei mir der Fall. Mit Hilfe der Anleitung zum Troubleshooting und den Infos aus diesem Issue kam ich dann zum Ziel:

gitlab-rails dbconsole
UPDATE ci_builds SET token_encrypted = NULL WHERE status in ('created', 'pending');

Wenn man sich das alles sparen möchte, dann lohnt es sich einen Blick auf unsere GitLab Angebote der NETWAYS Web Services zu werfen.

Gabriel Hartmann
Gabriel Hartmann
Systems Engineer

Gabriel hat 2016 als Auszubildender Fachinformatiker für Systemintegrator bei NETWAYS angefangen und 2019 die Ausbildung abgeschlossen. Als Mitglied des Web Services Teams kümmert er sich seither um viele technische Themen, die mit den NETWAYS Web Services und der Weiterentwicklung der Plattform zu tun haben. Aber auch im Support engagiert er sich, um den Kunden von NWS bei Fragen und Problemen zur Seite zu stehen.

Graphite-API für Grafana und Icinga Web 2

Ziel dieses Posts ist es, am Ende die Metriken über die Graphite-API als Backend für Grafana und das Icinga-Web-2-Module graphite betreiben zu können.

Grafana übernimmt hierbei optional die Visualisierung über eigene Dashboards, was ansonsten Graphite-Web leistet. Für Icinga Web 2 ist Grafana nur erforderlich, falls nicht das Module graphite zum Einsatz kommen soll, sondern stattdessen grafana zur Darstellung im Icinga Web 2 verwendet werden sollte.

Die Graphite-API ist in Python implementiert und soll hierbei via HTTPS angesprochen werden. Zusätzlich ist der Zugriff via Basis-Authentifizierung zu beschränken. Dies alles überlassen wir dem Apache, auch die API lassen wir mittels WSGI im Apache laufen.

Der Vorteil gegenüber dem Graphite-Web liegt darin, die ganzen Django-Bibliotheken nicht zu benötigen und auch kein DB-Backend a la SQLite, MySQL oder PostgreSQL. Nachteil ist, das Projekt Graphite-API wird nicht vom Graphite-Team betrieben, somit ist die Pflege und Aktualität nicht sichergestellt.
(mehr …)

Lennart Betz
Lennart Betz
Senior Consultant

Der diplomierte Mathematiker arbeitet bei NETWAYS im Bereich Consulting und bereichert seine Kunden mit seinem Wissen zu Icinga, Nagios und anderen Open Source Administrationstools. Im Büro erleuchtet Lennart seine Kollegen mit fundierten geschichtlichen Vorträgen die seinesgleichen suchen.

Cleanup your Docker Environment

Using Docker is pretty common meanwhile and a very good idea for development. Using many versions of your favourite language without messing up your host system, different types of deployments (e.g. web servers) or just testing production environment without operational support. The only drawback is that normally you don’t have a clue what’s going on behind the scenes. If you run out of disk space for the first time, you’re exactly at that point.

To apply first aid, you will be advised to use some curious cli hacks to clean up your system. Breaking fingers between grep, sed and awk works out well but is not very helpful – Especially if you want to remember what you did 3 months before 😉

Since Docker Api version 1.25 you have a couple of high level cli commands available doing exactly this job:

Minimal Cheat Sheet:

$ # Claimed disk space
$ docker system df
TYPE            TOTAL       ACTIVE      SIZE          RECLAIMABLE
Images          59          5           10.74GB       9.038GB (84%)
Containers      6           1           991kB         991kB (99%)
Local Volumes   216         1           5.876GB       5.876GB (100%)
Build Cache     0           0           0B            0B

$ # Cleanup disk space
$ docker system prune
WARNING! This will remove:
        - all stopped containers
        - all networks not used by at least one container
        - all dangling images
        - all dangling build cache
Are you sure you want to continue? [y/N] Y
Deleted Containers:
02401e1555e8e752d36198d982b5e4114d0999c7cca34a2353e8dc332faa4db5
997eac76d4a46515797027103967c61b46219ff8c70f6e0bb39bc2b975297fa5
23983ed8abaa60198b497e4b3788bb6de7d39d03f171f43e4ee865c0df318ab8
65bb90b9e7edcd2d13da3129664f8b74a72b011d56136cb28c687f1f8dd8e473
5218788bff77cc0c0cc03f79888ea61c3e27bf3ef0003e41fc231b8b6ecdcdc2

Deleted Images:
deleted: sha256:dccdc3cf7d581b80665bad309b66ba36d88219829e1ade951912dc122b657bfc
[...]

There is also an equivalent for images only:

$ docker image prune

You should definitely take a deeper look into the CLI commands. There are a lot of things that helps you to solve your every day problems!

Marius Hein
Marius Hein
Head of Development

Marius Hein ist schon seit 2003 bei NETWAYS. Er hat hier seine Ausbildung zum Fachinformatiker absolviert, dann als Application Developer gearbeitet und ist nun Leiter der Softwareentwicklung. Ausserdem ist er Mitglied im Icinga Team und verantwortet dort das Icinga Web.

Temperatur und Feuchtigkeit in Telegram vom RaspberryPI

Ich möchte hier beschreiben, wie man mit einem RaspberryPI die Temperatur und Feuchtigkeitswerte sich aufs Handy per Telegram schickt.
Verraussetzung ist ein RaspberryPI 3 b+ und ein Temperatur / Feuchtigkeitssensor, ich habe folgendes verwendet:

  • DSD TECH DHT22 AM2302 Temperatur und Luftfeuchtigkeit Sensor Modul für Arduino Raspberry Pi
  • RaspberryPI 3 B+

Anleitung wie man den Sensor an den RaspberryPI ansteckt, findet man reichlich im Netz z.B. Sensor-Einbau RaspberryPI/
Da in diesem Artikel auch schon beschrieben wird, wie man mit dem Tool Adafruit die Werte Temperatur und Feuchtigkeit ausliest, werde ich hier nicht genauer darauf eingehen.
Soviel, Ich lasse das Skript per cronjob zu bestimmten Zeiten ausführen und erhalte dann die Werte via Telegram auf mein Handy weitergeleitet.

Nur wie kann man sich die Werte auf das eigene Handy per Telegram senden lassen? Das werde ich hier kurz beschreiben.

Voraussetzung:

  • Handy mit der App Telegram (Apple IOs oder Android)

Als erstes müssen wir uns in Telegram einen eigenen Bot erstellen,  den wir später per API erreichen können,

wie das funktioniert, wird auch in vielen Webseiten bereits erklärt z.B. Telegram Bot erstellen

So, da der Bot jetzt bereit ist um per API Nachrichten zu empfangen, brauchen wir einen API-Aufruf der so aussehen kann:

curl -X POST 'https://api.telegram.org/botid:token/sendMessage?chat_id=id&text='$(/usr/local/sbin/AdafruitDHT.py 2302 4)'' > /dev/null 2>&1

Ich habe die Ausgaben die auf der Shell kommen nach /dev/null geleitet, denn die brauchen wir nicht, wenn es funktioniert.

Für die ersten Tests würde ich die Ausgabe schon sichtbar lassen, um den JSON-Output mal gesehen zu haben und gegebenenfalls Fehlermeldungen zu sehen.

curl -X POST 'https://api.telegram.org/botid:token/sendMessage?chat_id=id&text='$(/usr/local/sbin/AdafruitDHT.py 2302 4)'' | python -m json.tool

{
"ok": true,
"result": {
"chat": {
"first_name": "Johannes",
"id": 400269857,
"last_name": "Carraro",
"type": "private",
"username": "xxxx"
},
"date": 1563270619, <-- UNIXTIMESTAMP
"from": {
"first_name": "Raspberry",
"id": xxxxxx,
"is_bot": true,
"username": "xxxxx"
},
"message_id": 265,
"text": "Temp=20.8C::Humidity=75.8%"
}
}

Wie wir sehen war die Ausgabe erfolgreich und wir sollten auf dem Handy im Telegram eine neue Nachricht mit der Temperatur und Feuchtigkeit bekommen haben.

Man kann sich über den RaspberryPI mit verschiedenen Sensoren deren Werte so auf das Handy per Telegram schicken lassen, eine coole Sache.
Anwendungsbeispiel: Zimmergewächshaus, Zimmertemperatur, Außentemperatur etc.

Jetzt wünsche ich viel Erfolg beim nach basteln!

Natürlich kann ich jedem unsere Trainings nahelegen rundum OpenSource-Themen

Johannes Carraro
Johannes Carraro
Support Engineer

Bevor Johannes bei NETWAYS anheuerte war er knapp drei Jahre als Systemadministrator in Ansbach tätig. Seit Februar 2016 verstärkt er nun unser Managed Services Team als Systems Engineer. In seiner Freizeit spielt Johannes E-Gitarre in einer Metalband, bastelt an Linux Systemen zuhause herum und ertüchtigt sich beim Tischtennisspielen im Verein, bzw. Mountainbiken, Inlinern und nicht zuletzt Skifahren.