From 0ad751714a78e1c1ebdcfcc1111b793cf5a8b6dc Mon Sep 17 00:00:00 2001 From: Daniel Allaire Date: Fri, 13 Mar 2026 16:57:50 -0400 Subject: [PATCH] makefile --- Makefile | 29 ++-- README.md | 131 ++++++++++++------ ansible.cfg | 9 ++ ansible/deploy_life_noc.yml | 6 +- ansible/group_vars/all.yml.example | 21 +++ ansible/inventory.example | 2 +- ansible/roles/base/defaults/main.yml | 3 + ansible/roles/base/tasks/main.yml | 34 +++++ .../roles/businessprocess/defaults/main.yml | 4 + .../roles/businessprocess/handlers/main.yml | 4 + ansible/roles/businessprocess/tasks/main.yml | 36 +++++ ansible/roles/icinga2/defaults/main.yml | 6 + ansible/roles/icinga2/handlers/main.yml | 7 + ansible/roles/icinga2/tasks/main.yml | 55 ++++++++ .../roles/icinga2/templates/ido-mysql.conf.j2 | 13 ++ ansible/roles/icingaweb2/defaults/main.yml | 11 ++ ansible/roles/icingaweb2/handlers/main.yml | 4 + ansible/roles/icingaweb2/tasks/main.yml | 121 ++++++++++++++++ .../templates/authentication.ini.j2 | 3 + .../icingaweb2/templates/backends.ini.j2 | 3 + .../templates/commandtransports.ini.j2 | 3 + .../roles/icingaweb2/templates/config.ini.j2 | 10 ++ .../icingaweb2/templates/resources.ini.j2 | 21 +++ .../roles/icingaweb2/templates/roles.ini.j2 | 3 + ansible/roles/life_noc/defaults/main.yml | 4 +- ansible/roles/mariadb/defaults/main.yml | 1 + ansible/roles/mariadb/tasks/main.yml | 13 ++ ansible/site.yml | 10 ++ docs/deploiement-from-scratch.md | 80 +++++++++++ 29 files changed, 585 insertions(+), 62 deletions(-) create mode 100644 ansible.cfg create mode 100644 ansible/group_vars/all.yml.example create mode 100644 ansible/roles/base/defaults/main.yml create mode 100644 ansible/roles/base/tasks/main.yml create mode 100644 ansible/roles/businessprocess/defaults/main.yml create mode 100644 ansible/roles/businessprocess/handlers/main.yml create mode 100644 ansible/roles/businessprocess/tasks/main.yml create mode 100644 ansible/roles/icinga2/defaults/main.yml create mode 100644 ansible/roles/icinga2/handlers/main.yml create mode 100644 ansible/roles/icinga2/tasks/main.yml create mode 100644 ansible/roles/icinga2/templates/ido-mysql.conf.j2 create mode 100644 ansible/roles/icingaweb2/defaults/main.yml create mode 100644 ansible/roles/icingaweb2/handlers/main.yml create mode 100644 ansible/roles/icingaweb2/tasks/main.yml create mode 100644 ansible/roles/icingaweb2/templates/authentication.ini.j2 create mode 100644 ansible/roles/icingaweb2/templates/backends.ini.j2 create mode 100644 ansible/roles/icingaweb2/templates/commandtransports.ini.j2 create mode 100644 ansible/roles/icingaweb2/templates/config.ini.j2 create mode 100644 ansible/roles/icingaweb2/templates/resources.ini.j2 create mode 100644 ansible/roles/icingaweb2/templates/roles.ini.j2 create mode 100644 ansible/roles/mariadb/defaults/main.yml create mode 100644 ansible/roles/mariadb/tasks/main.yml create mode 100644 ansible/site.yml create mode 100644 docs/deploiement-from-scratch.md diff --git a/Makefile b/Makefile index 14fda4a..9674188 100644 --- a/Makefile +++ b/Makefile @@ -4,36 +4,36 @@ SHELL := /bin/bash PYTHON ?= python3 ANSIBLE_PLAYBOOK ?= ansible-playbook INVENTORY ?= ansible/inventory -PLAYBOOK ?= ansible/deploy_life_noc.yml -ARCHIVE ?= life-noc-poc-mock-first.zip +PLAYBOOK ?= ansible/site.yml +ARCHIVE ?= life-noc-from-scratch-debian12.zip PROJECT_NAME ?= life-noc GENERATORS := scripts/generate_services.py scripts/generate_bpm.py CHECKS := checks/check_life_noc_mock.sh checks/check_echeance_vie.sh ICINGA_FILES := $(wildcard icinga/commands/*.conf) $(wildcard icinga/hosts/*.conf) $(wildcard icinga/templates/*.conf) $(wildcard icinga/services/*.conf) -.PHONY: help all generate regen services bpm validate validate-yaml validate-python validate-shell validate-generated check mock-ok mock-warning mock-critical clean deploy deploy-no-bpm deploy-with-bpm package inventory-example info +.PHONY: help all generate regen services bpm validate validate-yaml validate-python validate-shell validate-generated check mock-ok mock-warning mock-critical clean bootstrap deploy deploy-no-bpm deploy-with-bpm package inventory-example vars-example info help: @echo "Life-NOC - cibles disponibles" @echo @echo " make generate Génère services Icinga + BPM" - @echo " make regen Alias de generate" @echo " make validate Valide YAML, Python, shell et artefacts générés" @echo " make check Génère puis valide" + @echo " make bootstrap Déploie la plateforme complète depuis Debian 12 vanille" + @echo " make deploy Alias de bootstrap" + @echo " make deploy-with-bpm Déploie explicitement avec artefact BPM" @echo " make mock-ok Teste la sonde mock en état OK" @echo " make mock-warning Teste la sonde mock en état WARNING" @echo " make mock-critical Teste la sonde mock en état CRITICAL" - @echo " make deploy Déploie via Ansible (BPM désactivé)" - @echo " make deploy-with-bpm Déploie via Ansible avec BPM activé" @echo " make package Crée une archive zip du dépôt" - @echo " make clean Supprime l'archive générée" + @echo " make inventory-example Rappelle comment préparer l'inventaire" + @echo " make vars-example Rappelle comment préparer les variables" @echo " make info Affiche les variables utiles" @echo @echo "Variables surchargables : INVENTORY=..., PLAYBOOK=..., ARCHIVE=..." all: check - regen: generate generate: services bpm @@ -72,10 +72,12 @@ mock-warning: mock-critical: @bash checks/check_life_noc_mock.sh --state CRITICAL --message "Action requise" --item-name "demo" --date "2026-03-13"; test $$? -eq 2 -deploy: check - $(ANSIBLE_PLAYBOOK) -i $(INVENTORY) $(PLAYBOOK) -e life_noc_bpm_deploy_enabled=false +bootstrap: check + $(ANSIBLE_PLAYBOOK) -i $(INVENTORY) $(PLAYBOOK) -deploy-no-bpm: deploy +deploy: bootstrap + +deploy-no-bpm: bootstrap deploy-with-bpm: check $(ANSIBLE_PLAYBOOK) -i $(INVENTORY) $(PLAYBOOK) -e life_noc_bpm_deploy_enabled=true @@ -89,7 +91,10 @@ clean: rm -f $(ARCHIVE) inventory-example: - @echo "Copier ansible/inventory.example vers ansible/inventory puis ajuster les hôtes." + @echo "Copier ansible/inventory.example vers ansible/inventory puis ajuster l'hôte, l'adresse et l'utilisateur ansible." + +vars-example: + @echo "Copier ansible/group_vars/all.yml.example vers ansible/group_vars/all.yml puis remplacer TOUS les mots de passe par les tiens." info: @echo "PROJECT_NAME=$(PROJECT_NAME)" diff --git a/README.md b/README.md index 29ffd00..1b15d22 100644 --- a/README.md +++ b/README.md @@ -4,33 +4,57 @@ Life-NOC applique la logique d'un centre d'opérations (NOC) à la vie quotidien Le but du projet est de transformer la charge mentale invisible en état observable, afin de savoir rapidement ce qui est sous contrôle, ce qui approche d'une échéance et ce qui mérite de l'attention. -## État actuel du dépôt +## Cible de ce dépôt -Cette version est une **POC fonctionnelle mock-first**. +Cette version vise désormais explicitement le scénario suivant : -Cela signifie que : +> **Debian 12 vanille + utilisateur `ansible` + clé SSH = plateforme Life-NOC complète** -- la structure métier est réelle ; -- les domaines et éléments de vie sont décrits dans `domains.yaml` ; -- les services Icinga sont générés automatiquement ; -- le BPM est généré automatiquement ; -- les sondes sont **mockées** par défaut et retournent **OK** tant qu'aucun état simulé n'est forcé. +Le dépôt automatise : + +- l'ajout du dépôt officiel Icinga +- l'installation de MariaDB +- l'installation d'Icinga 2 +- l'installation et la configuration d'IDO MySQL +- l'installation d'Apache et d'Icinga Web 2 +- l'installation du module Business Process +- le déploiement de Life-NOC +- la génération des services Icinga et de l'artefact BPM + +## État fonctionnel + +La modélisation métier reste **mock-first** : + +- les domaines et éléments de vie sont décrits dans `domains.yaml` +- les services Icinga sont générés automatiquement +- les sondes sont **mockées** par défaut +- l'état par défaut est **OK** Autrement dit, la POC valide : -- le modèle déclaratif ; -- la génération des artefacts ; -- le déploiement automatisé par Ansible ; -- la visualisation Icinga/BPM ; -- le remplacement futur des mocks par de vraies sondes. +- le modèle déclaratif +- la génération des artefacts +- le bootstrap complet de la plateforme +- le déploiement automatisé par Ansible +- l'affichage Icinga Web 2 +- l'évolution future vers de vraies sondes ## Structure du dépôt ```text life-noc/ ├── ansible/ +│ ├── group_vars/ +│ ├── inventory.example +│ ├── roles/ +│ │ ├── base/ +│ │ ├── mariadb/ +│ │ ├── icinga2/ +│ │ ├── icingaweb2/ +│ │ ├── businessprocess/ +│ │ └── life_noc/ │ ├── deploy_life_noc.yml -│ └── roles/life_noc/ +│ └── site.yml ├── bpm/ ├── checks/ ├── docs/ @@ -40,7 +64,9 @@ life-noc/ │ ├── services/ │ └── templates/ ├── scripts/ -└── domains.yaml +├── domains.yaml +├── Makefile +└── ansible.cfg ``` ## Source of truth @@ -62,7 +88,33 @@ Par défaut : - `mock_state = OK` - `mock_message = Sous contrôle` -## Génération +## Déploiement from scratch + +Depuis la machine de contrôle Debian 12 : + +```bash +cp ansible/inventory.example ansible/inventory +cp ansible/group_vars/all.yml.example ansible/group_vars/all.yml +``` + +Modifier ensuite : + +- l'hôte cible dans `ansible/inventory` +- les mots de passe dans `ansible/group_vars/all.yml` + +Puis lancer : + +```bash +make bootstrap +``` + +ou : + +```bash +ansible-playbook -i ansible/inventory ansible/site.yml +``` + +## Génération locale ### Générer les services Icinga @@ -70,13 +122,12 @@ Par défaut : python3 scripts/generate_services.py ``` -### Générer le BPM +### Générer l'artefact BPM ```bash python3 scripts/generate_bpm.py ``` - ## Makefile Le dépôt fournit un `Makefile` pour les gestes courants. @@ -87,37 +138,32 @@ Exemples : make generate make validate make check -make deploy +make bootstrap make deploy-with-bpm make package ``` +Pour la liste complète : + ```bash make help ``` -affiche la liste complète des cibles disponibles. +## Accès web attendus -## Déploiement Ansible +Une fois le playbook terminé, les chemins utiles sont typiquement : -Le déploiement repose sur le rôle `life_noc`. - -Exemple : - -```bash -cd ansible -ansible-playbook -i inventory deploy_life_noc.yml +```text +/icingaweb2 +/icingaweb2/monitoring/host/show?host=life-noc +/icingaweb2/monitoring/list/services?host_name=life-noc ``` -Variables importantes : +## Documentation complémentaire -- `life_noc_project_root` : chemin de déploiement du projet sur l'hôte cible -- `life_noc_icinga_conf_root` : racine de configuration Icinga pour Life-NOC -- `life_noc_plugin_dir` : répertoire des plugins Icinga -- `life_noc_validate_icinga` : valide la configuration avant reload -- `life_noc_reload_icinga` : recharge Icinga après déploiement -- `life_noc_bpm_deploy_enabled` : active le déploiement BPM vers le module Icinga Web 2 -- `life_noc_bpm_target_file` : destination du fichier BPM généré +- `docs/concept.md` +- `docs/architecture.md` +- `docs/deploiement-from-scratch.md` ## Philosophie de cette POC @@ -125,11 +171,12 @@ Cette POC ne prétend pas encore mesurer le réel. Elle sert à construire proprement : -- l'ossature du système ; -- la hiérarchie des domaines ; -- les conventions de nommage ; -- la chaîne de génération ; -- le déploiement ; -- l'intégration visuelle Icinga/BPM. +- l'ossature du système +- la hiérarchie des domaines +- les conventions de nommage +- la chaîne de génération +- le bootstrap serveur +- le déploiement +- l'intégration Icinga Web 2 Les vraies sondes viendront plus tard, en remplacement progressif des mocks. diff --git a/ansible.cfg b/ansible.cfg new file mode 100644 index 0000000..19ef756 --- /dev/null +++ b/ansible.cfg @@ -0,0 +1,9 @@ +[defaults] +inventory = ansible/inventory +host_key_checking = False +retry_files_enabled = False +interpreter_python = auto_silent +stdout_callback = yaml + +[ssh_connection] +pipelining = True diff --git a/ansible/deploy_life_noc.yml b/ansible/deploy_life_noc.yml index 40b79cc..162848c 100644 --- a/ansible/deploy_life_noc.yml +++ b/ansible/deploy_life_noc.yml @@ -1,5 +1 @@ -- hosts: icinga - become: true - - roles: - - life_noc +- import_playbook: site.yml diff --git a/ansible/group_vars/all.yml.example b/ansible/group_vars/all.yml.example new file mode 100644 index 0000000..cbee79a --- /dev/null +++ b/ansible/group_vars/all.yml.example @@ -0,0 +1,21 @@ +life_noc_fqdn: c7-life-noc-01 +life_noc_admin_user: icingadmin +life_noc_admin_password: CHANGE_ME_NOW + +life_noc_db_root_socket: /run/mysqld/mysqld.sock + +life_noc_db_icinga_name: icinga +life_noc_db_icinga_user: icinga +life_noc_db_icinga_password: CHANGE_ME_ICINGA_DB + +life_noc_db_web_name: icingaweb2 +life_noc_db_web_user: icingaweb2 +life_noc_db_web_password: CHANGE_ME_WEB_DB + +life_noc_icinga_repo_enabled: true +life_noc_icinga_repo_distribution: icinga-bookworm +life_noc_icinga_keyring_deb_url: https://packages.icinga.com/icinga-archive-keyring_latest+debian12.deb + +life_noc_businessprocess_enabled: true +life_noc_businessprocess_version: v2.5.2 +life_noc_businessprocess_repo: https://github.com/Icinga/icingaweb2-module-businessprocess.git diff --git a/ansible/inventory.example b/ansible/inventory.example index 7735e91..5021de5 100644 --- a/ansible/inventory.example +++ b/ansible/inventory.example @@ -1,2 +1,2 @@ [icinga] -localhost ansible_connection=local +life-noc-01 ansible_host=192.0.2.10 ansible_user=ansible diff --git a/ansible/roles/base/defaults/main.yml b/ansible/roles/base/defaults/main.yml new file mode 100644 index 0000000..4268107 --- /dev/null +++ b/ansible/roles/base/defaults/main.yml @@ -0,0 +1,3 @@ +life_noc_icinga_repo_enabled: true +life_noc_icinga_repo_distribution: icinga-bookworm +life_noc_icinga_keyring_deb_url: https://packages.icinga.com/icinga-archive-keyring_latest+debian12.deb diff --git a/ansible/roles/base/tasks/main.yml b/ansible/roles/base/tasks/main.yml new file mode 100644 index 0000000..4bd05ac --- /dev/null +++ b/ansible/roles/base/tasks/main.yml @@ -0,0 +1,34 @@ +- name: install base prerequisites + ansible.builtin.apt: + name: + - apt-transport-https + - ca-certificates + - curl + - git + - gnupg + - python3 + - python3-yaml + - unzip + state: present + update_cache: true + +- name: download icinga archive keyring package + ansible.builtin.get_url: + url: "{{ life_noc_icinga_keyring_deb_url }}" + dest: /tmp/icinga-archive-keyring.deb + mode: "0644" + when: life_noc_icinga_repo_enabled | bool + +- name: install icinga archive keyring package + ansible.builtin.apt: + deb: /tmp/icinga-archive-keyring.deb + state: present + when: life_noc_icinga_repo_enabled | bool + +- name: configure official icinga apt repository + ansible.builtin.apt_repository: + repo: "deb https://packages.icinga.com/debian {{ life_noc_icinga_repo_distribution }} main" + filename: icinga + state: present + update_cache: true + when: life_noc_icinga_repo_enabled | bool diff --git a/ansible/roles/businessprocess/defaults/main.yml b/ansible/roles/businessprocess/defaults/main.yml new file mode 100644 index 0000000..3efe261 --- /dev/null +++ b/ansible/roles/businessprocess/defaults/main.yml @@ -0,0 +1,4 @@ +life_noc_businessprocess_enabled: true +life_noc_businessprocess_version: v2.5.2 +life_noc_businessprocess_repo: https://github.com/Icinga/icingaweb2-module-businessprocess.git +life_noc_businessprocess_module_dir: /usr/share/icingaweb2/modules/businessprocess diff --git a/ansible/roles/businessprocess/handlers/main.yml b/ansible/roles/businessprocess/handlers/main.yml new file mode 100644 index 0000000..20f20b5 --- /dev/null +++ b/ansible/roles/businessprocess/handlers/main.yml @@ -0,0 +1,4 @@ +- name: restart apache2 + ansible.builtin.service: + name: apache2 + state: restarted diff --git a/ansible/roles/businessprocess/tasks/main.yml b/ansible/roles/businessprocess/tasks/main.yml new file mode 100644 index 0000000..1d9753b --- /dev/null +++ b/ansible/roles/businessprocess/tasks/main.yml @@ -0,0 +1,36 @@ +- name: install icinga web php libraries required by businessprocess + ansible.builtin.apt: + name: + - icinga-php-library + - icinga-php-thirdparty + state: present + update_cache: true + when: life_noc_businessprocess_enabled | bool + +- name: install businessprocess module from git + ansible.builtin.git: + repo: "{{ life_noc_businessprocess_repo }}" + dest: "{{ life_noc_businessprocess_module_dir }}" + version: "{{ life_noc_businessprocess_version }}" + force: true + when: life_noc_businessprocess_enabled | bool + notify: restart apache2 + +- name: ensure businessprocess config directories exist + ansible.builtin.file: + path: "{{ item }}" + state: directory + owner: root + group: icingaweb2 + mode: "2770" + loop: + - /etc/icingaweb2/modules/businessprocess + - /etc/icingaweb2/modules/businessprocess/processes + when: life_noc_businessprocess_enabled | bool + +- name: enable businessprocess module + ansible.builtin.command: icingacli module enable businessprocess + args: + creates: /etc/icingaweb2/enabledModules/businessprocess + when: life_noc_businessprocess_enabled | bool + notify: restart apache2 diff --git a/ansible/roles/icinga2/defaults/main.yml b/ansible/roles/icinga2/defaults/main.yml new file mode 100644 index 0000000..46b962d --- /dev/null +++ b/ansible/roles/icinga2/defaults/main.yml @@ -0,0 +1,6 @@ +life_noc_db_root_socket: /run/mysqld/mysqld.sock +life_noc_db_icinga_name: icinga +life_noc_db_icinga_user: icinga +life_noc_db_icinga_password: icinga-change-me +life_noc_icinga_ido_host: 127.0.0.1 +life_noc_icinga_ido_port: 3306 diff --git a/ansible/roles/icinga2/handlers/main.yml b/ansible/roles/icinga2/handlers/main.yml new file mode 100644 index 0000000..de559d6 --- /dev/null +++ b/ansible/roles/icinga2/handlers/main.yml @@ -0,0 +1,7 @@ +- name: restart icinga2 + ansible.builtin.service: + name: icinga2 + state: restarted + +- name: validate icinga2 + ansible.builtin.command: icinga2 daemon -C diff --git a/ansible/roles/icinga2/tasks/main.yml b/ansible/roles/icinga2/tasks/main.yml new file mode 100644 index 0000000..bb590b1 --- /dev/null +++ b/ansible/roles/icinga2/tasks/main.yml @@ -0,0 +1,55 @@ +- name: install icinga2 packages + ansible.builtin.apt: + name: + - icinga2 + - icinga2-ido-mysql + - monitoring-plugins-basic + - monitoring-plugins-common + state: present + update_cache: true + +- name: ensure icinga database exists + ansible.builtin.shell: | + mysql --socket={{ life_noc_db_root_socket }} -Nse "CREATE DATABASE IF NOT EXISTS {{ life_noc_db_icinga_name }} CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;" + changed_when: false + +- name: ensure icinga database user exists and has grants + ansible.builtin.shell: | + mysql --socket={{ life_noc_db_root_socket }} -Nse "GRANT ALTER, CREATE, SELECT, INSERT, UPDATE, DELETE, DROP, CREATE VIEW, INDEX, EXECUTE ON {{ life_noc_db_icinga_name }}.* TO '{{ life_noc_db_icinga_user }}'@'localhost' IDENTIFIED BY '{{ life_noc_db_icinga_password }}'; FLUSH PRIVILEGES;" + changed_when: false + +- name: check whether icinga ido schema is already imported + ansible.builtin.shell: | + mysql --socket={{ life_noc_db_root_socket }} -Nse "SELECT COUNT(*) FROM information_schema.tables WHERE table_schema='{{ life_noc_db_icinga_name }}' AND table_name='icinga_programstatus';" + register: life_noc_icinga_schema_check + changed_when: false + +- name: import icinga ido schema + ansible.builtin.shell: | + mysql --socket={{ life_noc_db_root_socket }} {{ life_noc_db_icinga_name }} < /usr/share/icinga2-ido-mysql/schema/mysql.sql + when: life_noc_icinga_schema_check.stdout | trim == '0' + +- name: install ido mysql feature configuration + ansible.builtin.template: + src: ido-mysql.conf.j2 + dest: /etc/icinga2/features-available/ido-mysql.conf + owner: root + group: root + mode: "0644" + notify: + - validate icinga2 + - restart icinga2 + +- name: enable ido-mysql feature + ansible.builtin.command: icinga2 feature enable ido-mysql + args: + creates: /etc/icinga2/features-enabled/ido-mysql.conf + notify: + - validate icinga2 + - restart icinga2 + +- name: enable and start icinga2 + ansible.builtin.service: + name: icinga2 + enabled: true + state: started diff --git a/ansible/roles/icinga2/templates/ido-mysql.conf.j2 b/ansible/roles/icinga2/templates/ido-mysql.conf.j2 new file mode 100644 index 0000000..ed29b96 --- /dev/null +++ b/ansible/roles/icinga2/templates/ido-mysql.conf.j2 @@ -0,0 +1,13 @@ +/** + * Managed by Ansible (Life-NOC) + */ +library "db_ido_mysql" + +object IdoMysqlConnection "ido-mysql" { + user = "{{ life_noc_db_icinga_user }}" + password = "{{ life_noc_db_icinga_password }}" + host = "{{ life_noc_icinga_ido_host }}" + port = {{ life_noc_icinga_ido_port }} + database = "{{ life_noc_db_icinga_name }}" + enable_ha = false +} diff --git a/ansible/roles/icingaweb2/defaults/main.yml b/ansible/roles/icingaweb2/defaults/main.yml new file mode 100644 index 0000000..706286b --- /dev/null +++ b/ansible/roles/icingaweb2/defaults/main.yml @@ -0,0 +1,11 @@ +life_noc_db_root_socket: /run/mysqld/mysqld.sock +life_noc_db_web_name: icingaweb2 +life_noc_db_web_user: icingaweb2 +life_noc_db_web_password: icingaweb2-change-me +life_noc_db_icinga_name: icinga +life_noc_db_icinga_user: icinga +life_noc_db_icinga_password: icinga-change-me +life_noc_admin_user: icingadmin +life_noc_admin_password: CHANGE_ME_NOW +life_noc_fqdn: localhost +life_noc_icinga2_command_pipe: /var/run/icinga2/cmd/icinga2.cmd diff --git a/ansible/roles/icingaweb2/handlers/main.yml b/ansible/roles/icingaweb2/handlers/main.yml new file mode 100644 index 0000000..20f20b5 --- /dev/null +++ b/ansible/roles/icingaweb2/handlers/main.yml @@ -0,0 +1,4 @@ +- name: restart apache2 + ansible.builtin.service: + name: apache2 + state: restarted diff --git a/ansible/roles/icingaweb2/tasks/main.yml b/ansible/roles/icingaweb2/tasks/main.yml new file mode 100644 index 0000000..dbe9f59 --- /dev/null +++ b/ansible/roles/icingaweb2/tasks/main.yml @@ -0,0 +1,121 @@ +- name: install icinga web and apache packages + ansible.builtin.apt: + name: + - apache2 + - icingaweb2 + - libapache2-mod-php8.2 + - php8.2-curl + - php8.2-gd + - php8.2-intl + - php8.2-mbstring + - php8.2-mysql + - php8.2-xml + state: present + update_cache: true + +- name: ensure apache2 is enabled and started + ansible.builtin.service: + name: apache2 + enabled: true + state: started + +- name: add web and monitoring users to icingaweb2 group + ansible.builtin.user: + name: "{{ item }}" + groups: icingaweb2 + append: true + loop: + - www-data + - nagios + +- name: ensure icingaweb2 database exists + ansible.builtin.shell: | + mysql --socket={{ life_noc_db_root_socket }} -Nse "CREATE DATABASE IF NOT EXISTS {{ life_noc_db_web_name }} CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;" + changed_when: false + +- name: ensure icingaweb2 database user exists and has grants + ansible.builtin.shell: | + mysql --socket={{ life_noc_db_root_socket }} -Nse "GRANT SELECT, INSERT, UPDATE, DELETE, DROP, CREATE VIEW, INDEX, EXECUTE ON {{ life_noc_db_web_name }}.* TO '{{ life_noc_db_web_user }}'@'localhost' IDENTIFIED BY '{{ life_noc_db_web_password }}'; FLUSH PRIVILEGES;" + changed_when: false + +- name: check whether icingaweb2 schema is already imported + ansible.builtin.shell: | + mysql --socket={{ life_noc_db_root_socket }} -Nse "SELECT COUNT(*) FROM information_schema.tables WHERE table_schema='{{ life_noc_db_web_name }}' AND table_name='icingaweb_user';" + register: life_noc_web_schema_check + changed_when: false + +- name: import icingaweb2 schema + ansible.builtin.shell: | + mysql --socket={{ life_noc_db_root_socket }} {{ life_noc_db_web_name }} < /usr/share/icingaweb2/etc/schema/mysql.schema.sql + when: life_noc_web_schema_check.stdout | trim == '0' + +- name: generate icingaweb2 admin password hash + ansible.builtin.command: >- + php -r 'echo password_hash(getenv("LIFE_NOC_ADMIN_PASSWORD"), PASSWORD_DEFAULT);' + environment: + LIFE_NOC_ADMIN_PASSWORD: "{{ life_noc_admin_password }}" + register: life_noc_admin_password_hash + changed_when: false + no_log: true + +- name: check whether icingaweb2 admin user exists + ansible.builtin.shell: | + mysql --socket={{ life_noc_db_root_socket }} -Nse "SELECT COUNT(*) FROM {{ life_noc_db_web_name }}.icingaweb_user WHERE name='{{ life_noc_admin_user }}';" + register: life_noc_admin_user_check + changed_when: false + no_log: true + +- name: create icingaweb2 admin user + ansible.builtin.shell: | + mysql --socket={{ life_noc_db_root_socket }} -Nse "INSERT INTO {{ life_noc_db_web_name }}.icingaweb_user (name, active, password_hash) VALUES ('{{ life_noc_admin_user }}', 1, '{{ life_noc_admin_password_hash.stdout }}');" + when: life_noc_admin_user_check.stdout | trim == '0' + no_log: true + +- name: ensure icingaweb2 config directories exist + ansible.builtin.file: + path: "{{ item.path }}" + state: directory + owner: root + group: icingaweb2 + mode: "{{ item.mode }}" + loop: + - { path: '/etc/icingaweb2', mode: '2770' } + - { path: '/etc/icingaweb2/enabledModules', mode: '2770' } + - { path: '/etc/icingaweb2/modules', mode: '2770' } + - { path: '/etc/icingaweb2/modules/monitoring', mode: '2770' } + - { path: '/etc/icingaweb2/preferences', mode: '2770' } + +- name: deploy icingaweb2 core configuration + ansible.builtin.template: + src: "{{ item.src }}" + dest: "{{ item.dest }}" + owner: root + group: icingaweb2 + mode: "0660" + loop: + - { src: 'config.ini.j2', dest: '/etc/icingaweb2/config.ini' } + - { src: 'resources.ini.j2', dest: '/etc/icingaweb2/resources.ini' } + - { src: 'authentication.ini.j2', dest: '/etc/icingaweb2/authentication.ini' } + - { src: 'roles.ini.j2', dest: '/etc/icingaweb2/roles.ini' } + notify: restart apache2 + +- name: deploy monitoring module configuration + ansible.builtin.template: + src: "{{ item.src }}" + dest: "{{ item.dest }}" + owner: root + group: icingaweb2 + mode: "0660" + loop: + - { src: 'backends.ini.j2', dest: '/etc/icingaweb2/modules/monitoring/backends.ini' } + - { src: 'commandtransports.ini.j2', dest: '/etc/icingaweb2/modules/monitoring/commandtransports.ini' } + notify: restart apache2 + +- name: enable icingaweb2 modules + ansible.builtin.command: "icingacli module enable {{ item }}" + args: + creates: "/etc/icingaweb2/enabledModules/{{ item }}" + loop: + - monitoring + - doc + notify: restart apache2 diff --git a/ansible/roles/icingaweb2/templates/authentication.ini.j2 b/ansible/roles/icingaweb2/templates/authentication.ini.j2 new file mode 100644 index 0000000..8311091 --- /dev/null +++ b/ansible/roles/icingaweb2/templates/authentication.ini.j2 @@ -0,0 +1,3 @@ +[icingaweb2] +backend = "db" +resource = "icingaweb2" diff --git a/ansible/roles/icingaweb2/templates/backends.ini.j2 b/ansible/roles/icingaweb2/templates/backends.ini.j2 new file mode 100644 index 0000000..9cdf19e --- /dev/null +++ b/ansible/roles/icingaweb2/templates/backends.ini.j2 @@ -0,0 +1,3 @@ +[icinga2_ido_mysql] +type = "ido" +resource = "icinga2_ido_mysql" diff --git a/ansible/roles/icingaweb2/templates/commandtransports.ini.j2 b/ansible/roles/icingaweb2/templates/commandtransports.ini.j2 new file mode 100644 index 0000000..38a85d3 --- /dev/null +++ b/ansible/roles/icingaweb2/templates/commandtransports.ini.j2 @@ -0,0 +1,3 @@ +[icinga2] +transport = "local" +path = "{{ life_noc_icinga2_command_pipe }}" diff --git a/ansible/roles/icingaweb2/templates/config.ini.j2 b/ansible/roles/icingaweb2/templates/config.ini.j2 new file mode 100644 index 0000000..b826249 --- /dev/null +++ b/ansible/roles/icingaweb2/templates/config.ini.j2 @@ -0,0 +1,10 @@ +[global] +show_stacktraces = "0" +config_backend = "ini" + +[logging] +log = "syslog" +level = "ERROR" + +[themes] +default = "Icinga" diff --git a/ansible/roles/icingaweb2/templates/resources.ini.j2 b/ansible/roles/icingaweb2/templates/resources.ini.j2 new file mode 100644 index 0000000..f4107af --- /dev/null +++ b/ansible/roles/icingaweb2/templates/resources.ini.j2 @@ -0,0 +1,21 @@ +[icingaweb2] +type = "db" +db = "mysql" +host = "localhost" +port = "3306" +dbname = "{{ life_noc_db_web_name }}" +username = "{{ life_noc_db_web_user }}" +password = "{{ life_noc_db_web_password }}" +charset = "utf8mb4" +use_ssl = "0" + +[icinga2_ido_mysql] +type = "db" +db = "mysql" +host = "localhost" +port = "3306" +dbname = "{{ life_noc_db_icinga_name }}" +username = "{{ life_noc_db_icinga_user }}" +password = "{{ life_noc_db_icinga_password }}" +charset = "latin1" +use_ssl = "0" diff --git a/ansible/roles/icingaweb2/templates/roles.ini.j2 b/ansible/roles/icingaweb2/templates/roles.ini.j2 new file mode 100644 index 0000000..a2fdaa7 --- /dev/null +++ b/ansible/roles/icingaweb2/templates/roles.ini.j2 @@ -0,0 +1,3 @@ +[administrators] +users = "{{ life_noc_admin_user }}" +permissions = "*" diff --git a/ansible/roles/life_noc/defaults/main.yml b/ansible/roles/life_noc/defaults/main.yml index c4d22fd..74a3ee6 100644 --- a/ansible/roles/life_noc/defaults/main.yml +++ b/ansible/roles/life_noc/defaults/main.yml @@ -3,7 +3,7 @@ life_noc_icinga_conf_root: /etc/icinga2/conf.d/life-noc life_noc_plugin_dir: /usr/lib/nagios/plugins life_noc_validate_icinga: true life_noc_reload_icinga: true -life_noc_bpm_deploy_enabled: false -life_noc_bpm_target_file: /var/lib/icingaweb2/modules/bpm/config/life-noc.json +life_noc_bpm_deploy_enabled: true +life_noc_bpm_target_file: /etc/icingaweb2/modules/businessprocess/processes/life-noc.json life_noc_owner: root life_noc_group: root diff --git a/ansible/roles/mariadb/defaults/main.yml b/ansible/roles/mariadb/defaults/main.yml new file mode 100644 index 0000000..305d874 --- /dev/null +++ b/ansible/roles/mariadb/defaults/main.yml @@ -0,0 +1 @@ +life_noc_db_root_socket: /run/mysqld/mysqld.sock diff --git a/ansible/roles/mariadb/tasks/main.yml b/ansible/roles/mariadb/tasks/main.yml new file mode 100644 index 0000000..cdc4e3c --- /dev/null +++ b/ansible/roles/mariadb/tasks/main.yml @@ -0,0 +1,13 @@ +- name: install mariadb server + ansible.builtin.apt: + name: + - mariadb-server + - mariadb-client + state: present + update_cache: true + +- name: enable and start mariadb + ansible.builtin.service: + name: mariadb + enabled: true + state: started diff --git a/ansible/site.yml b/ansible/site.yml new file mode 100644 index 0000000..9d9e825 --- /dev/null +++ b/ansible/site.yml @@ -0,0 +1,10 @@ +- hosts: icinga + become: true + + roles: + - base + - mariadb + - icinga2 + - icingaweb2 + - businessprocess + - life_noc diff --git a/docs/deploiement-from-scratch.md b/docs/deploiement-from-scratch.md new file mode 100644 index 0000000..d88af82 --- /dev/null +++ b/docs/deploiement-from-scratch.md @@ -0,0 +1,80 @@ +# Déploiement from scratch Debian 12 + +Objectif : partir d'une **VM Debian 12 vanille** disposant seulement : + +- d'un utilisateur `ansible` +- d'une paire de clés SSH fonctionnelle +- d'un accès réseau aux dépôts Debian et Icinga + +et obtenir automatiquement : + +- MariaDB +- Icinga 2 +- IDO MySQL +- Apache +- Icinga Web 2 +- module Business Process +- Life-NOC déployé et généré + +## Préparation côté poste de contrôle + +Depuis la machine Debian 12 qui lance Ansible : + +```bash +cp ansible/inventory.example ansible/inventory +cp ansible/group_vars/all.yml.example ansible/group_vars/all.yml +``` + +Puis ajuster : + +- l'adresse IP ou le FQDN de la cible dans `ansible/inventory` +- les mots de passe dans `ansible/group_vars/all.yml` +- au besoin le nom DNS final via `life_noc_fqdn` + +## Lancement + +```bash +make bootstrap +``` + +ou directement : + +```bash +ansible-playbook -i ansible/inventory ansible/site.yml +``` + +## Résultat attendu + +À la fin du playbook : + +- Icinga 2 est actif +- Icinga Web 2 est servi par Apache +- le backend IDO est branché sur MariaDB +- Life-NOC est généré depuis `domains.yaml` +- la configuration Life-NOC est déployée dans `/etc/icinga2/conf.d/life-noc` +- le plugin mock est installé +- l'utilisateur d'administration Icinga Web 2 existe + +## URLs utiles + +Selon le vhost Apache de la cible : + +- `http:///icingaweb2` +- `http:///icingaweb2/monitoring/host/show?host=life-noc` +- `http:///icingaweb2/monitoring/list/services?host_name=life-noc` + +## Identifiants + +L'utilisateur initial d'administration est piloté par : + +- `life_noc_admin_user` +- `life_noc_admin_password` + +## Remarque BPM + +Le module Business Process est installé et activé. +Le dépôt déploie en plus l'artefact généré `bpm/life-noc.json` sous : + +- `/etc/icingaweb2/modules/businessprocess/processes/life-noc.json` + +Cela prépare l'intégration BPM côté dépôt. Selon l'usage exact retenu dans l'interface, l'import ou l'adaptation finale de cet artefact peut être ajusté ensuite sans remettre en cause le bootstrap complet de la plateforme.