serveur_icingaweb2 : Icinga Web 2 (UI + module IcingaDB) — éprouvé

App PHP (php8.4-fpm) + nginx local, exposée par l'edge (auto-dérivé).
Config par fichiers .ini (config/resources/authentication/roles + module
icingadb), pas d'assistant. Base IcingaDB via resoudre_base. Auth LDAP
direct (client_pki sur sup-01) — pas d'OIDC natif (SSO-proxy = raffinement).

Prouvé : testmail (LDAP) se connecte (/dashboard), module IcingaDB affiche
la supervision (hôte icinga). Déploiement failed=0 (frictions dans le
simulateur curl, pas le rôle). Reste : module BPM.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Daniel Allaire 2026-07-03 16:57:04 -04:00
parent 36cf62236d
commit b3b972fb5e
14 changed files with 250 additions and 2 deletions

View file

@ -3,6 +3,16 @@
## 2026-07-03
### Ajouté
- **Rôle `serveur_icingaweb2` — Icinga Web 2 (UI native) + module IcingaDB : éprouvé.** App PHP
(php8.4-fpm) servie par un **nginx local**, exposée par l'edge (`icinga.lab.chezlepro.internal`,
auto-dérivé : vhost + cert SAN + A PowerDNS + alias plancher). Config **par fichiers `.ini`**
(config/resources/authentication/roles + module `icingadb`), pas d'assistant de setup. Base
IcingaDB via `resoudre_base` (registre). **Auth LDAP direct** vers OpenLDAP (LDAPS, `client_pki`
sur `sup-01`) — icingaweb2 n'a pas d'OIDC natif ; SSO-par-proxy = raffinement futur. **Prouvé** :
`testmail` (LDAP) se connecte (`/dashboard`), et le **module IcingaDB affiche la supervision**
(hôte `icinga`). Déploiement `failed=0` (le rôle est bon ; les frictions étaient dans le
simulateur de login curl : contrôle de cookie `_checkCookie`, champs `uid`/`submit_login`,
valeur CSRF avant `name`). **Reste de la pile Icinga : le module BPM.**
- **Cœur Icinga éprouvé (supervision active).** `serveur_icinga` (cœur : `icinga2` + `icingadb` +
`icingadb-redis`) déployé sur `sup-01` (🔧→⭐), base `icingadb` PostgreSQL via le registre.
**Prouvé** : 3 services actifs, et le moteur **supervise** — IcingaDB peuplée (1 hôte, 12

View file

@ -43,8 +43,10 @@ Chezlepro » prouvé : `testmail` LDAP → Keycloak → Grafana). Plus **`serveu
sur `forge-01`, PostgreSQL via registre, **branché au SSO OIDC** — 2e app : `testmail` se connecte,
compte auto-créé). Et **`serveur_redis`** (sur `data-sql-01`, cache réseau, auth obligatoire —
SET/GET prouvé, accès sans mot de passe refusé). Et le **cœur `serveur_icinga`** (sur `sup-01` :
icinga2 + icingadb + redis dédié, base PostgreSQL via registre — supervise, IcingaDB peuplée ;
**Icinga Web 2 + BPM différés**). Restent « code non éprouvé » : `serveur_sendmail`.
icinga2 + icingadb + redis dédié, base PostgreSQL via registre — supervise, IcingaDB peuplée) +
**`serveur_icingaweb2`** (UI native, PHP/nginx local, module IcingaDB, **auth LDAP**`testmail`
se connecte et voit la supervision ; **reste le module BPM**). Restent « code non éprouvé » :
`serveur_sendmail`.
> **Lacunes connues sur Keycloak** (déployé mais pas complet) : la **fédération LDAP** (Keycloak
> → OpenLDAP, modèle d'identité A) n'est **pas encore automatisée** dans le rôle ; l'**edge nginx**

View file

@ -0,0 +1,15 @@
---
- name: Appliquer le groupe serveur_icingaweb2
hosts: serveur_icingaweb2
become: true
gather_facts: true
pre_tasks:
- name: Vérifier que la cible est Debian
ansible.builtin.assert:
that:
- ansible_facts.distribution == "Debian"
fail_msg: "Ce playbook est prévu pour Debian."
roles:
- serveur_icingaweb2

View file

@ -0,0 +1,45 @@
---
# Icinga Web 2 (UI native Icinga) + module IcingaDB, sur le nœud de supervision.
# App PHP servie par nginx local + php-fpm ; l'edge nginx proxifie par nom.
# Auth LDAP direct (OpenLDAP) — icingaweb2 n'a pas d'OIDC natif ; SSO via proxy = raffinement.
serveur_icingaweb2_paquets:
- icingadb-web # module IcingaDB (tire icingaweb2 en dépendance)
- php8.4-fpm
- php8.4-cli
- php8.4-pgsql
- php8.4-ldap
- php8.4-intl
- php8.4-gd
- php8.4-curl
- php8.4-xml
- php8.4-mbstring
- nginx
serveur_icingaweb2_php_fpm_service: "php8.4-fpm"
serveur_icingaweb2_php_fpm_socket: "/run/php/php8.4-fpm.sock"
serveur_icingaweb2_nginx_service: "nginx"
# Publication : nginx LOCAL sur ce port ; l'edge proxifie icinga.<domaine> ici.
serveur_icingaweb2_hostname: "icinga.{{ domaine_interne }}"
serveur_icingaweb2_http_port: 8080
serveur_icingaweb2_docroot: "/usr/share/icingaweb2/public"
serveur_icingaweb2_config_dir: "/etc/icingaweb2"
# Base IcingaDB (via le registre — même consommateur que le moteur).
serveur_icingaweb2_icinga_groupe: "serveur_icinga"
# Redis IcingaDB (local au nœud de supervision).
serveur_icingaweb2_redis_host: "127.0.0.1"
serveur_icingaweb2_redis_port: 6380
# Authentification LDAP (OpenLDAP, LDAPS via la confiance step_ca / client_pki).
serveur_icingaweb2_ldap_url: "ldaps://id-ldap-01.{{ domaine_interne }}"
serveur_icingaweb2_ldap_port: 636
serveur_icingaweb2_ldap_base: "dc={{ domaine_interne.split('.') | join(',dc=') }}"
serveur_icingaweb2_ldap_users_dn: "ou=people,dc={{ domaine_interne.split('.') | join(',dc=') }}"
serveur_icingaweb2_ldap_bind_dn: "cn=admin,dc={{ domaine_interne.split('.') | join(',dc=') }}"
serveur_icingaweb2_ldap_bind_password: "{{ vault_openldap_admin | default('') }}"
serveur_icingaweb2_ldap_user_class: "inetOrgPerson"
serveur_icingaweb2_ldap_user_attr: "uid"
# Qui reçoit le rôle Administrateur (liste d'uid séparés par des virgules).
serveur_icingaweb2_admins: "testmail"

View file

@ -0,0 +1,12 @@
---
- name: Redémarrer php-fpm
ansible.builtin.systemd:
name: "{{ serveur_icingaweb2_php_fpm_service }}"
state: restarted
when: not ansible_check_mode
- name: Recharger nginx
ansible.builtin.systemd:
name: "{{ serveur_icingaweb2_nginx_service }}"
state: reloaded
when: not ansible_check_mode

View file

@ -0,0 +1,6 @@
---
# Empreinte ressources — Icinga Web 2 (PHP-FPM + nginx). Co-localisé au moteur Icinga.
setops_empreinte:
coeurs: 1
memoire_mo: 512
disque_go: 3

View file

@ -0,0 +1,84 @@
---
- name: Résoudre la base IcingaDB depuis le registre (rôle partagé)
ansible.builtin.include_role:
name: resoudre_base
vars:
resoudre_base_groupe: "{{ serveur_icingaweb2_icinga_groupe }}"
- name: Installer Icinga Web 2 + module IcingaDB + PHP-FPM + nginx
ansible.builtin.apt:
name: "{{ serveur_icingaweb2_paquets }}"
state: present
update_cache: true
- name: Ajouter www-data au groupe icingaweb2 (lecture de la config)
ansible.builtin.user:
name: www-data
groups: icingaweb2
append: true
notify: Redémarrer php-fpm
- name: Assurer le répertoire du module IcingaDB
ansible.builtin.file:
path: "{{ serveur_icingaweb2_config_dir }}/modules/icingadb"
state: directory
owner: root
group: icingaweb2
mode: "0750"
- name: Déployer la configuration icingaweb2 (.ini)
ansible.builtin.template:
src: "{{ item.s }}"
dest: "{{ serveur_icingaweb2_config_dir }}/{{ item.d }}"
owner: root
group: icingaweb2
mode: "0640"
no_log: "{{ item.secret | default(false) }}"
loop:
- { s: config.ini.j2, d: config.ini }
- { s: resources.ini.j2, d: resources.ini, secret: true }
- { s: authentication.ini.j2, d: authentication.ini }
- { s: roles.ini.j2, d: roles.ini }
- { s: icingadb-config.ini.j2, d: modules/icingadb/config.ini }
- { s: icingadb-redis.ini.j2, d: modules/icingadb/redis.ini }
loop_control:
label: "{{ item.d }}"
notify: Redémarrer php-fpm
- name: Activer le module IcingaDB
ansible.builtin.command: icingacli module enable icingadb
args:
creates: "{{ serveur_icingaweb2_config_dir }}/enabledModules/icingadb"
when: not ansible_check_mode
- name: Déployer le vhost nginx local d'Icinga Web 2
ansible.builtin.template:
src: nginx.conf.j2
dest: /etc/nginx/sites-available/icingaweb2.conf
owner: root
group: root
mode: "0644"
notify: Recharger nginx
- name: Activer le vhost Icinga Web 2
ansible.builtin.file:
src: /etc/nginx/sites-available/icingaweb2.conf
dest: /etc/nginx/sites-enabled/icingaweb2.conf
state: link
notify: Recharger nginx
- name: Retirer le site nginx par défaut
ansible.builtin.file:
path: /etc/nginx/sites-enabled/default
state: absent
notify: Recharger nginx
- name: Activer et démarrer PHP-FPM et nginx
ansible.builtin.systemd:
name: "{{ item }}"
enabled: true
state: started
loop:
- "{{ serveur_icingaweb2_php_fpm_service }}"
- "{{ serveur_icingaweb2_nginx_service }}"
when: not ansible_check_mode

View file

@ -0,0 +1,7 @@
; Géré par Set-OPS (rôle serveur_icingaweb2). Ne pas éditer à la main.
[icingaweb2]
backend = "ldap"
resource = "icingaweb_ldap"
user_class = "{{ serveur_icingaweb2_ldap_user_class }}"
user_name_attribute = "{{ serveur_icingaweb2_ldap_user_attr }}"
base_dn = "{{ serveur_icingaweb2_ldap_users_dn }}"

View file

@ -0,0 +1,9 @@
; Géré par Set-OPS (rôle serveur_icingaweb2). Ne pas éditer à la main.
[global]
show_stacktraces = "0"
config_backend = "ini"
[logging]
log = "syslog"
level = "ERROR"
application = "icingaweb2"

View file

@ -0,0 +1,3 @@
; Géré par Set-OPS (rôle serveur_icingaweb2). Ne pas éditer à la main.
[icingadb]
resource = "icingadb"

View file

@ -0,0 +1,4 @@
; Géré par Set-OPS (rôle serveur_icingaweb2). Ne pas éditer à la main.
[redis1]
host = "{{ serveur_icingaweb2_redis_host }}"
port = "{{ serveur_icingaweb2_redis_port }}"

View file

@ -0,0 +1,27 @@
# Géré par Set-OPS (rôle serveur_icingaweb2). Ne pas éditer à la main.
# nginx LOCAL : sert Icinga Web 2 (PHP-FPM). L'edge nginx proxifie par nom vers ce port.
server {
listen {{ serveur_icingaweb2_http_port }};
listen [::]:{{ serveur_icingaweb2_http_port }};
server_name {{ serveur_icingaweb2_hostname }};
root {{ serveur_icingaweb2_docroot }};
index index.php;
location / {
try_files $uri $uri/ /index.php$is_args$args;
}
location ~ ^/index\.php {
fastcgi_pass unix:{{ serveur_icingaweb2_php_fpm_socket }};
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME {{ serveur_icingaweb2_docroot }}/index.php;
fastcgi_param ICINGAWEB_CONFIGDIR {{ serveur_icingaweb2_config_dir }};
fastcgi_param REMOTE_USER $remote_user;
}
location ~ /\.ht {
deny all;
}
}

View file

@ -0,0 +1,20 @@
; Géré par Set-OPS (rôle serveur_icingaweb2). Ne pas éditer à la main.
[icingadb]
type = "db"
db = "pgsql"
host = "{{ resoudre_base_db_host }}"
port = "{{ resoudre_base_db_port }}"
dbname = "{{ resoudre_base_entree.base }}"
username = "{{ resoudre_base_entree.proprietaire }}"
password = "{{ resoudre_base_db_password }}"
charset = "UTF8"
[icingaweb_ldap]
type = "ldap"
hostname = "{{ serveur_icingaweb2_ldap_url | regex_replace('^ldaps?://', '') }}"
port = "{{ serveur_icingaweb2_ldap_port }}"
encryption = "ldaps"
root_dn = "{{ serveur_icingaweb2_ldap_base }}"
bind_dn = "{{ serveur_icingaweb2_ldap_bind_dn }}"
bind_pw = "{{ serveur_icingaweb2_ldap_bind_password }}"
timeout = "5"

View file

@ -0,0 +1,4 @@
; Géré par Set-OPS (rôle serveur_icingaweb2). Ne pas éditer à la main.
[Administrators]
users = "{{ serveur_icingaweb2_admins }}"
permissions = "*"