From 9ecb9985fbff7cfb559a0a28a4093cefce6b1987 Mon Sep 17 00:00:00 2001 From: phil Date: Tue, 27 Dec 2022 10:43:32 +0100 Subject: [PATCH] Erstelle Grafana-Rolle --- README.md | 48 +++++++++++++++++++++++++++++++++++++ defaults/main.yml | 4 ++++ files/fail2ban/filter.conf | 10 ++++++++ files/fail2ban/jail.conf | 7 ++++++ files/grafana.monit | 8 +++++++ files/influxdb.monit | 9 +++++++ handlers/main.yml | 18 ++++++++++++++ meta/main.yml | 10 ++++++++ tasks/database.yml | 14 +++++++++++ tasks/grafana.yml | 29 ++++++++++++++++++++++ tasks/main.yml | 12 ++++++++++ tasks/packages.yml | 18 ++++++++++++++ tasks/webserver.yml | 16 +++++++++++++ templates/apache2-site.conf | 26 ++++++++++++++++++++ templates/grafana.ini | 27 +++++++++++++++++++++ vars/main.yml | 2 ++ 16 files changed, 258 insertions(+) create mode 100644 README.md create mode 100644 defaults/main.yml create mode 100644 files/fail2ban/filter.conf create mode 100644 files/fail2ban/jail.conf create mode 100644 files/grafana.monit create mode 100644 files/influxdb.monit create mode 100644 handlers/main.yml create mode 100644 meta/main.yml create mode 100644 tasks/database.yml create mode 100644 tasks/grafana.yml create mode 100644 tasks/main.yml create mode 100644 tasks/packages.yml create mode 100644 tasks/webserver.yml create mode 100644 templates/apache2-site.conf create mode 100644 templates/grafana.ini create mode 100644 vars/main.yml diff --git a/README.md b/README.md new file mode 100644 index 0000000..39bda39 --- /dev/null +++ b/README.md @@ -0,0 +1,48 @@ +Grafana +======= + +[Grafana](https://grafana.com) ist eine Redering-Enging für Zeitreihen. + +# Ausführen der Rolle +- In der jeweiligen `host_vars`-Datei die Variablen in einer `grafana`-Map setzen: + | Variable | Wert | Beschreibung | + |----------|------|--------------| + | `domain` | string | Domainname der Grafana-Instanz | +- Rolle ausführen: + ```Shell + ansible-playbook playbooks/grafana.yml + ``` +- Grafana aufrufen - der Erstlogin erfolgt mit `admin:amdin`. Anschließend das Passwort ändern und in unsere Zugangsdatenbank eintragen. + +# Grafana mit Icinga verknüpfen +Mit Grafana lassen sich die Performance-Daten aus den Icinga-Checks grafisch in Icinga-Web2 darstellen: +- Neue "Data Source" hinzufügen und InfluxDB als Datenquelle angeben +- Unte `/org/apikeys` einen API-Schlüssel erzeugen +- Nun die Icinga-Dashboards unter `/dashboard/import` importieren. Dazu [hier](https://github.com/Mikesch-mp/icingaweb2-module-grafana/tree/master/dashboards/influxdb) die Dateien `base-metrics.json` und `icinga2-default.json` herunter laden. +- Beim Import von `icinga2-default.json` müssen die [Queries](https://github.com/Mikesch-mp/icingaweb2-module-grafana/blob/master/doc/06-create-grafana-dashboards-influxdb.md#Templating) (Hostname, Service, Command) angepasst werden +- Die Darstellung des Grafen für den http-Check anpassen, da sie ansonsten keine Aussagekraft hat: + - Dazu das Dashboard ''icinga2-default'' öffnen und einen beliebigen http-Check auswählen + - ''Edit Panel'': + - Rechts in den Panel-Optionen: ''Axes'' --> ''Left Y'': Unit auf ''Seconds'' und ''Scale'' --> ''log(base 2)'' + - Unten bei der Query-Abfrage: ''Transform'' --> ''Filter by name '' --> ''size'' deaktivieren +- Das [Icingaweb2-Modul](https://github.com/Mikesch-mp/icingaweb2-module-grafana|Icingaweb2-Modul) herunter laden und entpacken. Als Pfad kann `/data/icingaweb2-modules` gewählt werden +- Modulepfad in `/etc/icingaweb2/global.ini` anpassen: + ```Ini + [global] + ... + module_path = "/usr/share/icingaweb2/modules:/data/icingaweb2-modules" + ``` +- Verzeichnis `/etc/icingaweb2/modules/grafana` anlegen und Besitzrechte analog zu den anderen Verzeichnissen vergeben +- Modul in Icingaweb2 `/config/modules#!/grafana/config` konfigurieren: + - host: Grafana-Domain + - Default Dashboard UID: Dazu in Grafana eine Grafik öffnen und über die *Share*-Funktion die Panel-ID aus der URL kopieren + - Grafana access: Indirect proxy + - Authentication type: API Token +- Das Redering der Graphen erfolgt mit dem [Grafana Image Renderer](https://grafana.com/grafana/plugins/grafana-image-renderer) - Installation mit: + ```Shell + grafana-cli plugins install grafana-image-renderer + ``` +- Zusätzlich muss Chromium installiert werden (automatisch durch die Rolle) +- [Hostalive](https://dokuwiki.tachtler.net/doku.php?id=tachtler:icinga2_-_grafana#icingaweb2add_new_grafana_graphhostalive)-Graph hinzufügen: + - Dashboard name: base-metrics + - Dashborad UID und Panel-ID erneut aus dem Share-Link kopieren diff --git a/defaults/main.yml b/defaults/main.yml new file mode 100644 index 0000000..ed95b8e --- /dev/null +++ b/defaults/main.yml @@ -0,0 +1,4 @@ +--- +grafana_db: grafana +grafana_db_user: grafana +grafana_db_password: "{{ lookup('password', '/tmp/grafana_database_pwd length=42 chars=ascii_letters,digits') }}" diff --git a/files/fail2ban/filter.conf b/files/fail2ban/filter.conf new file mode 100644 index 0000000..bf549a8 --- /dev/null +++ b/files/fail2ban/filter.conf @@ -0,0 +1,10 @@ +[INCLUDES] +before = common.conf + +[Definition] +failregex = ^ lvl=[a-zA-z]* msg=\"Invalid username or password\" (?:\S*=(?:\".*\"|\S*) )*remote_addr= + +ignoreregex = + +[Init] +datepattern = ^t=%%Y-%%m-%%dT%%H:%%M:%%S%%z \ No newline at end of file diff --git a/files/fail2ban/jail.conf b/files/fail2ban/jail.conf new file mode 100644 index 0000000..9d1d552 --- /dev/null +++ b/files/fail2ban/jail.conf @@ -0,0 +1,7 @@ +[grafana] +enabled = true +findtime = 3600 +bantime = 3600 +port = http,https +filter = grafana +logpath = /var/log/grafana/grafana.log \ No newline at end of file diff --git a/files/grafana.monit b/files/grafana.monit new file mode 100644 index 0000000..3fdb0b4 --- /dev/null +++ b/files/grafana.monit @@ -0,0 +1,8 @@ +# {{ ansible_managed }} + +check process grafana with pidfile /var/run/grafana/grafana-server.pid + group monitor + start program = "/bin/systemctl start grafana-server.service" + stop program = "/bin/systemctl stop grafana-server.service" + if failed host localhost port 3000 with timeout 15 seconds for 3 times within 4 cycles then restart + if 5 restarts with 5 cycles then timeout diff --git a/files/influxdb.monit b/files/influxdb.monit new file mode 100644 index 0000000..4d529d3 --- /dev/null +++ b/files/influxdb.monit @@ -0,0 +1,9 @@ +# {{ ansible_managed }} + +check process influxdb + matching "/usr/bin/influxd -config /etc/influxdb/influxdb.conf" + group database + start program = "/usr/sbin/service influxd start" + stop program = "/usr/sbin/service influxd stop" + if failed host localhost port 8088 with timeout 15 seconds for 3 times within 4 cycles then restart + if 5 restarts with 5 cycles then timeout diff --git a/handlers/main.yml b/handlers/main.yml new file mode 100644 index 0000000..7c80396 --- /dev/null +++ b/handlers/main.yml @@ -0,0 +1,18 @@ +--- +- name: get certificate + ansible.builtin.command: dehydrated --cron -g + +- name: restart grafana + ansible.builtin.service: + name: grafana-server + state: restarted + +- name: reload monit + ansible.builtin.service: + name: monit + state: reloaded + +- name: reload fail2ban + ansible.builtin.service: + name: fail2ban + state: reloaded diff --git a/meta/main.yml b/meta/main.yml new file mode 100644 index 0000000..8e4798e --- /dev/null +++ b/meta/main.yml @@ -0,0 +1,10 @@ +galaxy_info: + author: systemausfall.org + description: Role to install Grafana + company: Sense.Lab e.V. + license: GPLv3 + min_ansible_version: "2.9" + platforms: + - name: Debian + versions: + - bullseye diff --git a/tasks/database.yml b/tasks/database.yml new file mode 100644 index 0000000..aeb235b --- /dev/null +++ b/tasks/database.yml @@ -0,0 +1,14 @@ +--- +- name: "database | Erstelle Datenbank" + ansible.builtin.mysql_db: + name: "{{ grafana_db }}" + login_unix_socket: "{{ mysql_socket }}" + login_user: root + +- name: "database | Erstelle Datenbank-Nutzer" + ansible.builtin.mysql_user: + name: "{{ grafana_db_user }}" + password: "{{ grafana_db_password }}" + priv: "{{ grafana_db }}.*:ALL" + login_unix_socket: "{{ mysql_socket }}" + login_user: root diff --git a/tasks/grafana.yml b/tasks/grafana.yml new file mode 100644 index 0000000..1f7a33a --- /dev/null +++ b/tasks/grafana.yml @@ -0,0 +1,29 @@ +--- +- name: "grafana | Erzeuge Grafana-Konfiguration" + ansible.builtin.template: + src: grafana.ini + dest: /etc/grafana/grafana.ini + mode: 0640 + notify: restart grafana + +- name: "grafana | Aktiviere Monit-Ueberwachung" + ansible.builtin.copy: + src: "{{ item }}.monit" + dest: "/etc/monit/conf-enabled/{{ item }}" + mode: 0644 + notify: reload monit + loop: + - grafana + - influxdb + +- name: "grafana | fail2ban-Konfiguration kopieren" + ansible.builtin.copy: + src: "fail2ban/{{ item.src }}" + dest: "/etc/fail2ban/{{ item.dest }}" + mode: 0644 + loop: + - src: jail.conf + dest: jail.d/grafana.conf + - src: filter.conf + dest: filter.d/grafana.conf + notify: reload fail2ban diff --git a/tasks/main.yml b/tasks/main.yml new file mode 100644 index 0000000..eff01da --- /dev/null +++ b/tasks/main.yml @@ -0,0 +1,12 @@ +--- +- import_tasks: packages.yml + tags: packages + +- import_tasks: database.yml + delegate_to: "{{ database_host }}" + +- import_tasks: grafana.yml + tags: grafana + +- import_tasks: webserver.yml + tags: webserver diff --git a/tasks/packages.yml b/tasks/packages.yml new file mode 100644 index 0000000..41b9250 --- /dev/null +++ b/tasks/packages.yml @@ -0,0 +1,18 @@ +--- +- name: "packages | Fuege apt-key hinzu" + ansible.builtin.apt_key: + url: https://packages.grafana.com/gpg.key + +- name: "packages | Fuege deb-Repository hinzu" + ansible.builtin.apt_repository: + repo: deb https://packages.grafana.com/oss/deb stable main + filename: grafana + +- name: "packages | Installiere Grafana" + ansible.builtin.apt: + name: grafana + +- name: "packages | Installiere chromium" + ansible.builtin.apt: + name: chromium + install_recommends: false diff --git a/tasks/webserver.yml b/tasks/webserver.yml new file mode 100644 index 0000000..f7a08d4 --- /dev/null +++ b/tasks/webserver.yml @@ -0,0 +1,16 @@ +--- +- name: "webserver | Erzeuge Letsencrypt-Zertifikat" + ansible.builtin.lineinfile: + path: /etc/dehydrated/domains.txt + line: "{{ grafana.domain }}" + notify: get certificate + +- name: "webserver | Grafana-Seitenkonfigurationen kopieren" + ansible.builtin.template: + src: apache2-site.conf + dest: "/etc/apache2/sites-available/{{ grafana.domain }}.conf" + mode: 0644 + +- name: "webserver | Grafana-Seitenkonfiguration aktivieren" + ansible.builtin.command: "a2ensite {{ grafana.domain }}" + notify: reload apache2 diff --git a/templates/apache2-site.conf b/templates/apache2-site.conf new file mode 100644 index 0000000..cdc4354 --- /dev/null +++ b/templates/apache2-site.conf @@ -0,0 +1,26 @@ + + ServerName {{ grafana.domain }} + Redirect permanent / https://{{ grafana.domain }}/ + + + + + ServerName {{ grafana.domain }} + Protocols h2 http/1.1 + DocumentRoot /var/www/html + IncludeOptional /etc/apache2/conf-available/add-headers.conf + + ErrorLog ${APACHE_LOG_DIR}/grafana.error.log + #CustomLog ${APACHE_LOG_DIR}/grafana.access.log combined + LogLevel Error + + SSLEngine On + SSLCertificateFile /var/lib/dehydrated/certs/{{ grafana.domain }}/fullchain.pem + SSLCertificateKeyFile /var/lib/dehydrated/certs/{{ grafana.domain }}/privkey.pem + + ProxyPreserveHost On + ProxyPass /.well-known ! + ProxyPass / http://127.0.0.1:3000/ + ProxyPassReverse / http://127.0.0.1:3000/ + + diff --git a/templates/grafana.ini b/templates/grafana.ini new file mode 100644 index 0000000..2f5add1 --- /dev/null +++ b/templates/grafana.ini @@ -0,0 +1,27 @@ +# {{ ansible_managed }} + +[server] +domain = {{ grafana.domain }} + +[database] +type = mysql +host = 127.0.0.1:3306 +name = {{ grafana_db }} +user = {{ grafana_db_user }} +password = {{ grafana_db_password }} + +[security] +disable_gravatar = true +cookie_secure = true +cookie_samesite = strict +strict_transport_security = true +strict_transport_security_max_age_seconds = 86400 +strict_transport_security_preload = true +strict_transport_security_subdomains = true +x_content_type_options = true +x_xss_protection = true +content_security_policy = true +content_security_policy_template = """script-src 'unsafe-eval' 'strict-dynamic' $NONCE;object-src 'none';font-src 'self';style-src 'self' 'unsafe-inline';img-src 'self' data:;base-uri 'self';connect-src 'self' grafana.com;manifest-src 'self';media-src 'none';form-action 'self';""" + +[auth.anonymous] +enabled = false diff --git a/vars/main.yml b/vars/main.yml new file mode 100644 index 0000000..09050e8 --- /dev/null +++ b/vars/main.yml @@ -0,0 +1,2 @@ +--- +# vars file for roles/grafana