diff --git a/archives/README.md b/archives/README.md
new file mode 100644
index 0000000..d874769
--- /dev/null
+++ b/archives/README.md
@@ -0,0 +1,7 @@
+# Archives
+
+Contient :
+- legacy
+- variantes remplacées
+- artefacts déplacés pendant migration
+
diff --git a/docs/vieustoq/01_charte_fondatrice.md b/archives/legacy-docs/vieustoq/01_charte_fondatrice.md
similarity index 100%
rename from docs/vieustoq/01_charte_fondatrice.md
rename to archives/legacy-docs/vieustoq/01_charte_fondatrice.md
diff --git a/docs/vieustoq/02_reglement_regie_interne.md b/archives/legacy-docs/vieustoq/02_reglement_regie_interne.md
similarity index 100%
rename from docs/vieustoq/02_reglement_regie_interne.md
rename to archives/legacy-docs/vieustoq/02_reglement_regie_interne.md
diff --git a/docs/vieustoq/03_guide_demarrage_rapide.md b/archives/legacy-docs/vieustoq/03_guide_demarrage_rapide.md
similarity index 100%
rename from docs/vieustoq/03_guide_demarrage_rapide.md
rename to archives/legacy-docs/vieustoq/03_guide_demarrage_rapide.md
diff --git a/docs/vieustoq/2025-10-11 - L'Alliance Boréale - Partenariats.md b/archives/legacy-docs/vieustoq/2025-10-11 - L'Alliance Boréale - Partenariats.md
similarity index 100%
rename from docs/vieustoq/2025-10-11 - L'Alliance Boréale - Partenariats.md
rename to archives/legacy-docs/vieustoq/2025-10-11 - L'Alliance Boréale - Partenariats.md
diff --git a/docs/vieustoq/doc_10_contrat_adhesion.md b/archives/legacy-docs/vieustoq/doc_10_contrat_adhesion.md
similarity index 100%
rename from docs/vieustoq/doc_10_contrat_adhesion.md
rename to archives/legacy-docs/vieustoq/doc_10_contrat_adhesion.md
diff --git a/docs/vieustoq/doc_11_resolutions_ca.md b/archives/legacy-docs/vieustoq/doc_11_resolutions_ca.md
similarity index 100%
rename from docs/vieustoq/doc_11_resolutions_ca.md
rename to archives/legacy-docs/vieustoq/doc_11_resolutions_ca.md
diff --git a/docs/vieustoq/doc_12_plan_transition_obnl.md b/archives/legacy-docs/vieustoq/doc_12_plan_transition_obnl.md
similarity index 100%
rename from docs/vieustoq/doc_12_plan_transition_obnl.md
rename to archives/legacy-docs/vieustoq/doc_12_plan_transition_obnl.md
diff --git a/docs/vieustoq/doc_14_registraire_yaml.md b/archives/legacy-docs/vieustoq/doc_14_registraire_yaml.md
similarity index 100%
rename from docs/vieustoq/doc_14_registraire_yaml.md
rename to archives/legacy-docs/vieustoq/doc_14_registraire_yaml.md
diff --git a/docs/vieustoq/document_01_charte_fondatrice.md b/archives/legacy-docs/vieustoq/document_01_charte_fondatrice.md
similarity index 100%
rename from docs/vieustoq/document_01_charte_fondatrice.md
rename to archives/legacy-docs/vieustoq/document_01_charte_fondatrice.md
diff --git a/docs/vieustoq/document_04_modele_financement_hybride.md b/archives/legacy-docs/vieustoq/document_04_modele_financement_hybride.md
similarity index 100%
rename from docs/vieustoq/document_04_modele_financement_hybride.md
rename to archives/legacy-docs/vieustoq/document_04_modele_financement_hybride.md
diff --git a/docs/vieustoq/document_04_modele_financement_hybride_v1.1.md b/archives/legacy-docs/vieustoq/document_04_modele_financement_hybride_v1.1.md
similarity index 100%
rename from docs/vieustoq/document_04_modele_financement_hybride_v1.1.md
rename to archives/legacy-docs/vieustoq/document_04_modele_financement_hybride_v1.1.md
diff --git a/docs/vieustoq/document_05_protocole_audit_pair.md b/archives/legacy-docs/vieustoq/document_05_protocole_audit_pair.md
similarity index 100%
rename from docs/vieustoq/document_05_protocole_audit_pair.md
rename to archives/legacy-docs/vieustoq/document_05_protocole_audit_pair.md
diff --git a/docs/vieustoq/document_05_protocole_audit_pair_a_pair.md b/archives/legacy-docs/vieustoq/document_05_protocole_audit_pair_a_pair.md
similarity index 100%
rename from docs/vieustoq/document_05_protocole_audit_pair_a_pair.md
rename to archives/legacy-docs/vieustoq/document_05_protocole_audit_pair_a_pair.md
diff --git a/docs/vieustoq/document_06_charte_banque_de_temps.md b/archives/legacy-docs/vieustoq/document_06_charte_banque_de_temps.md
similarity index 100%
rename from docs/vieustoq/document_06_charte_banque_de_temps.md
rename to archives/legacy-docs/vieustoq/document_06_charte_banque_de_temps.md
diff --git a/docs/vieustoq/document_06_charte_banque_temps.md b/archives/legacy-docs/vieustoq/document_06_charte_banque_temps.md
similarity index 100%
rename from docs/vieustoq/document_06_charte_banque_temps.md
rename to archives/legacy-docs/vieustoq/document_06_charte_banque_temps.md
diff --git a/docs/pile opérateur/README.md b/archives/pre-migration/docs-pile-operateur/README.md
similarity index 100%
rename from docs/pile opérateur/README.md
rename to archives/pre-migration/docs-pile-operateur/README.md
diff --git a/docs/00-fondements/00 - Manifeste.md b/archives/pre-migration/duplicates/00 - Manifeste.md
similarity index 100%
rename from docs/00-fondements/00 - Manifeste.md
rename to archives/pre-migration/duplicates/00 - Manifeste.md
diff --git a/docs/00-fondements/00-manifeste.md b/archives/pre-migration/duplicates/00-manifeste.md
similarity index 100%
rename from docs/00-fondements/00-manifeste.md
rename to archives/pre-migration/duplicates/00-manifeste.md
diff --git a/docs/20-rag/03_Cadre_Conformite_Label_Prestige(1).md b/archives/pre-migration/duplicates/03_Cadre_Conformite_Label_Prestige(1).md
similarity index 100%
rename from docs/20-rag/03_Cadre_Conformite_Label_Prestige(1).md
rename to archives/pre-migration/duplicates/03_Cadre_Conformite_Label_Prestige(1).md
diff --git a/docs/20-rag/devis(2).md b/archives/pre-migration/duplicates/devis(2).md
similarity index 100%
rename from docs/20-rag/devis(2).md
rename to archives/pre-migration/duplicates/devis(2).md
diff --git a/docs/README.md b/docs/README.md
new file mode 100644
index 0000000..68b6b70
--- /dev/null
+++ b/docs/README.md
@@ -0,0 +1,16 @@
+# Documentation canonique
+
+Ce dossier contient la documentation de référence de l'Alliance Boréale.
+
+Branches principales :
+- fondements
+- modele
+- architecture
+- gouvernance
+- decisions
+- politiques
+- ecosystemes
+- guides
+- corpus-a-integrer
+- diffusion
+
diff --git a/docs/10-architecture/10 - Constitution des couches du modèle Boréal.md b/docs/architecture/10 - Constitution des couches du modèle Boréal.md
similarity index 100%
rename from docs/10-architecture/10 - Constitution des couches du modèle Boréal.md
rename to docs/architecture/10 - Constitution des couches du modèle Boréal.md
diff --git a/docs/10-architecture/10 - Les 8 couches du modèle Boréal.md b/docs/architecture/10 - Les 8 couches du modèle Boréal.md
similarity index 100%
rename from docs/10-architecture/10 - Les 8 couches du modèle Boréal.md
rename to docs/architecture/10 - Les 8 couches du modèle Boréal.md
diff --git a/docs/10-architecture/10 - Modèle Boréal.md b/docs/architecture/10 - Modèle Boréal.md
similarity index 100%
rename from docs/10-architecture/10 - Modèle Boréal.md
rename to docs/architecture/10 - Modèle Boréal.md
diff --git a/docs/10-architecture/10 - Nomenclature mnémotechnique.md b/docs/architecture/10 - Nomenclature mnémotechnique.md
similarity index 100%
rename from docs/10-architecture/10 - Nomenclature mnémotechnique.md
rename to docs/architecture/10 - Nomenclature mnémotechnique.md
diff --git a/docs/10-architecture/10 - Stack opérateur de référence (C1-C5).md b/docs/architecture/10 - Stack opérateur de référence (C1-C5).md
similarity index 100%
rename from docs/10-architecture/10 - Stack opérateur de référence (C1-C5).md
rename to docs/architecture/10 - Stack opérateur de référence (C1-C5).md
diff --git a/docs/10-architecture/10 - Structure YAML du registraire.md b/docs/architecture/10 - Structure YAML du registraire.md
similarity index 100%
rename from docs/10-architecture/10 - Structure YAML du registraire.md
rename to docs/architecture/10 - Structure YAML du registraire.md
diff --git a/docs/10-architecture/2026-01-29 - Cache OVH - NGINX.md b/docs/architecture/2026-01-29 - Cache OVH - NGINX.md
similarity index 100%
rename from docs/10-architecture/2026-01-29 - Cache OVH - NGINX.md
rename to docs/architecture/2026-01-29 - Cache OVH - NGINX.md
diff --git a/docs/10-architecture/Architecture_Deterministe_Alliance_Boreale_Whitepaper.md b/docs/architecture/Architecture_Deterministe_Alliance_Boreale_Whitepaper.md
similarity index 100%
rename from docs/10-architecture/Architecture_Deterministe_Alliance_Boreale_Whitepaper.md
rename to docs/architecture/Architecture_Deterministe_Alliance_Boreale_Whitepaper.md
diff --git a/docs/10-architecture/Architecture_Deterministe_Diagrammes_Visuels.md b/docs/architecture/Architecture_Deterministe_Diagrammes_Visuels.md
similarity index 100%
rename from docs/10-architecture/Architecture_Deterministe_Diagrammes_Visuels.md
rename to docs/architecture/Architecture_Deterministe_Diagrammes_Visuels.md
diff --git a/docs/10-architecture/Forgejo_dans_le_cycle_vivant.md b/docs/architecture/Forgejo_dans_le_cycle_vivant.md
similarity index 100%
rename from docs/10-architecture/Forgejo_dans_le_cycle_vivant.md
rename to docs/architecture/Forgejo_dans_le_cycle_vivant.md
diff --git a/docs/10-architecture/checklist_reunion.md b/docs/architecture/checklist_reunion.md
similarity index 100%
rename from docs/10-architecture/checklist_reunion.md
rename to docs/architecture/checklist_reunion.md
diff --git a/docs/10-architecture/guide_formation.md b/docs/architecture/guide_formation.md
similarity index 100%
rename from docs/10-architecture/guide_formation.md
rename to docs/architecture/guide_formation.md
diff --git a/docs/10-architecture/readme_package.md b/docs/architecture/readme_package.md
similarity index 100%
rename from docs/10-architecture/readme_package.md
rename to docs/architecture/readme_package.md
diff --git a/docs/10-architecture/resolution_adoption.md b/docs/architecture/resolution_adoption.md
similarity index 100%
rename from docs/10-architecture/resolution_adoption.md
rename to docs/architecture/resolution_adoption.md
diff --git a/docs/10-architecture/scripts_migration.sh b/docs/architecture/scripts_migration.sh
similarity index 100%
rename from docs/10-architecture/scripts_migration.sh
rename to docs/architecture/scripts_migration.sh
diff --git a/docs/10-architecture/templates_automation.md b/docs/architecture/templates_automation.md
similarity index 100%
rename from docs/10-architecture/templates_automation.md
rename to docs/architecture/templates_automation.md
diff --git a/docs/20-rag/01 - Charte fondatrice.md b/docs/corpus-a-integrer/01 - Charte fondatrice.md
similarity index 100%
rename from docs/20-rag/01 - Charte fondatrice.md
rename to docs/corpus-a-integrer/01 - Charte fondatrice.md
diff --git a/docs/20-rag/02 - Règlement de régie interne.md b/docs/corpus-a-integrer/02 - Règlement de régie interne.md
similarity index 100%
rename from docs/20-rag/02 - Règlement de régie interne.md
rename to docs/corpus-a-integrer/02 - Règlement de régie interne.md
diff --git a/docs/TODO.md b/docs/corpus-a-integrer/TODO.md
similarity index 100%
rename from docs/TODO.md
rename to docs/corpus-a-integrer/TODO.md
diff --git a/docs/TRANSMISSION.md b/docs/corpus-a-integrer/TRANSMISSION.md
similarity index 100%
rename from docs/TRANSMISSION.md
rename to docs/corpus-a-integrer/TRANSMISSION.md
diff --git a/docs/50-annexes/05-correspondance-ISO27001.md b/docs/corpus-a-integrer/annexes/05-correspondance-ISO27001.md
similarity index 100%
rename from docs/50-annexes/05-correspondance-ISO27001.md
rename to docs/corpus-a-integrer/annexes/05-correspondance-ISO27001.md
diff --git a/docs/index.md b/docs/corpus-a-integrer/index.md
similarity index 100%
rename from docs/index.md
rename to docs/corpus-a-integrer/index.md
diff --git a/docs/pile opérateur/adr/ADR-C5-CTRL-001 — FastAPI comme plan de contrôle en C5 et ERPLibre comme portail back-office.md b/docs/decisions/adr/ADR-C5-CTRL-001 — FastAPI comme plan de contrôle en C5 et ERPLibre comme portail back-office.md
similarity index 100%
rename from docs/pile opérateur/adr/ADR-C5-CTRL-001 — FastAPI comme plan de contrôle en C5 et ERPLibre comme portail back-office.md
rename to docs/decisions/adr/ADR-C5-CTRL-001 — FastAPI comme plan de contrôle en C5 et ERPLibre comme portail back-office.md
diff --git a/docs/pile opérateur/adr/ADR-OBS-001 — Loki comme backend de logs de référence.md b/docs/decisions/adr/ADR-OBS-001 — Loki comme backend de logs de référence.md
similarity index 100%
rename from docs/pile opérateur/adr/ADR-OBS-001 — Loki comme backend de logs de référence.md
rename to docs/decisions/adr/ADR-OBS-001 — Loki comme backend de logs de référence.md
diff --git a/docs/pile opérateur/adr/ADR-OPS-STACK-001 — Pile opérateur de référence (C1–C5).md b/docs/decisions/adr/ADR-OPS-STACK-001 — Pile opérateur de référence (C1–C5).md
similarity index 100%
rename from docs/pile opérateur/adr/ADR-OPS-STACK-001 — Pile opérateur de référence (C1–C5).md
rename to docs/decisions/adr/ADR-OPS-STACK-001 — Pile opérateur de référence (C1–C5).md
diff --git a/docs/2026-02-03 - Présentation d'Alliance Boréale - Rencontres Linux.odp b/docs/diffusion/conferences/2026-02-03-Rencontres-Linux.odp
similarity index 100%
rename from docs/2026-02-03 - Présentation d'Alliance Boréale - Rencontres Linux.odp
rename to docs/diffusion/conferences/2026-02-03-Rencontres-Linux.odp
diff --git a/docs/Alliance_Boreale_Conferences.pptx b/docs/diffusion/conferences/Alliance_Boreale_Conferences.pptx
similarity index 100%
rename from docs/Alliance_Boreale_Conferences.pptx
rename to docs/diffusion/conferences/Alliance_Boreale_Conferences.pptx
diff --git a/docs/Conference_01_Rideau_ou_Coffre_Fort.pptx b/docs/diffusion/conferences/Conference_01_Rideau_ou_Coffre_Fort.pptx
similarity index 100%
rename from docs/Conference_01_Rideau_ou_Coffre_Fort.pptx
rename to docs/diffusion/conferences/Conference_01_Rideau_ou_Coffre_Fort.pptx
diff --git a/docs/Conference_02_Colonisation_Numerique.pptx b/docs/diffusion/conferences/Conference_02_Colonisation_Numerique.pptx
similarity index 100%
rename from docs/Conference_02_Colonisation_Numerique.pptx
rename to docs/diffusion/conferences/Conference_02_Colonisation_Numerique.pptx
diff --git a/docs/assets/logo-alliance-boreale.svg b/docs/diffusion/visuels/assets/logo-alliance-boreale.svg
similarity index 100%
rename from docs/assets/logo-alliance-boreale.svg
rename to docs/diffusion/visuels/assets/logo-alliance-boreale.svg
diff --git a/docs/40-ecosystemes/00-chezlepro.md b/docs/ecosystemes/00-chezlepro.md
similarity index 100%
rename from docs/40-ecosystemes/00-chezlepro.md
rename to docs/ecosystemes/00-chezlepro.md
diff --git a/docs/40-ecosystemes/01-technolibre.md b/docs/ecosystemes/01-technolibre.md
similarity index 100%
rename from docs/40-ecosystemes/01-technolibre.md
rename to docs/ecosystemes/01-technolibre.md
diff --git a/docs/40-ecosystemes/02-district16.md b/docs/ecosystemes/02-district16.md
similarity index 100%
rename from docs/40-ecosystemes/02-district16.md
rename to docs/ecosystemes/02-district16.md
diff --git a/docs/00-fondements/00 - Charte cognitive.md b/docs/fondements/00 - Charte cognitive.md
similarity index 100%
rename from docs/00-fondements/00 - Charte cognitive.md
rename to docs/fondements/00 - Charte cognitive.md
diff --git a/docs/00-fondements/00 - Glossaire.md b/docs/fondements/00 - Glossaire.md
similarity index 100%
rename from docs/00-fondements/00 - Glossaire.md
rename to docs/fondements/00 - Glossaire.md
diff --git a/docs/gouvernance/Certificate_Policy_Alliance_Boreale_v1.0.md b/docs/gouvernance.pre-migration-20260309-105729/Certificate_Policy_Alliance_Boreale_v1.0.md
similarity index 100%
rename from docs/gouvernance/Certificate_Policy_Alliance_Boreale_v1.0.md
rename to docs/gouvernance.pre-migration-20260309-105729/Certificate_Policy_Alliance_Boreale_v1.0.md
diff --git a/docs/gouvernance/Certification_Practice_Statement_Alliance_Boreale_v1.0.md b/docs/gouvernance.pre-migration-20260309-105729/Certification_Practice_Statement_Alliance_Boreale_v1.0.md
similarity index 100%
rename from docs/gouvernance/Certification_Practice_Statement_Alliance_Boreale_v1.0.md
rename to docs/gouvernance.pre-migration-20260309-105729/Certification_Practice_Statement_Alliance_Boreale_v1.0.md
diff --git a/docs/gouvernance/INSTRUCTIONS_CLAUDE_v2.1.md b/docs/gouvernance.pre-migration-20260309-105729/INSTRUCTIONS_CLAUDE_v2.1.md
similarity index 100%
rename from docs/gouvernance/INSTRUCTIONS_CLAUDE_v2.1.md
rename to docs/gouvernance.pre-migration-20260309-105729/INSTRUCTIONS_CLAUDE_v2.1.md
diff --git a/docs/gouvernance/Pacte_Collaboration_Claude_President.md b/docs/gouvernance.pre-migration-20260309-105729/Pacte_Collaboration_Claude_President.md
similarity index 100%
rename from docs/gouvernance/Pacte_Collaboration_Claude_President.md
rename to docs/gouvernance.pre-migration-20260309-105729/Pacte_Collaboration_Claude_President.md
diff --git a/docs/gouvernance/guide-utilisation-claude.md b/docs/gouvernance.pre-migration-20260309-105729/guide-utilisation-claude.md
similarity index 100%
rename from docs/gouvernance/guide-utilisation-claude.md
rename to docs/gouvernance.pre-migration-20260309-105729/guide-utilisation-claude.md
diff --git a/docs/gouvernance/pacte-conseiller-strategique.md b/docs/gouvernance.pre-migration-20260309-105729/pacte-conseiller-strategique.md
similarity index 100%
rename from docs/gouvernance/pacte-conseiller-strategique.md
rename to docs/gouvernance.pre-migration-20260309-105729/pacte-conseiller-strategique.md
diff --git a/docs/gouvernance/proposition_nouvelle_place.md b/docs/gouvernance.pre-migration-20260309-105729/proposition_nouvelle_place.md
similarity index 100%
rename from docs/gouvernance/proposition_nouvelle_place.md
rename to docs/gouvernance.pre-migration-20260309-105729/proposition_nouvelle_place.md
diff --git a/docs/constitution/00_Charte_Cognitive_Alliance_Boreale.md b/docs/gouvernance/00_Charte_Cognitive_Alliance_Boreale.md
similarity index 100%
rename from docs/constitution/00_Charte_Cognitive_Alliance_Boreale.md
rename to docs/gouvernance/00_Charte_Cognitive_Alliance_Boreale.md
diff --git a/docs/00_Etat_Depot_Vivant_v1.md b/docs/gouvernance/00_Etat_Depot_Vivant_v1.md
similarity index 100%
rename from docs/00_Etat_Depot_Vivant_v1.md
rename to docs/gouvernance/00_Etat_Depot_Vivant_v1.md
diff --git a/docs/constitution/01_charte_fondatrice_v_3.md b/docs/gouvernance/01_charte_fondatrice_v_3.md
similarity index 100%
rename from docs/constitution/01_charte_fondatrice_v_3.md
rename to docs/gouvernance/01_charte_fondatrice_v_3.md
diff --git a/docs/constitution/02_Reglement_de_Regie_Interne_biomimetique_autopoietique_v3.md b/docs/gouvernance/02_Reglement_de_Regie_Interne_biomimetique_autopoietique_v3.md
similarity index 100%
rename from docs/constitution/02_Reglement_de_Regie_Interne_biomimetique_autopoietique_v3.md
rename to docs/gouvernance/02_Reglement_de_Regie_Interne_biomimetique_autopoietique_v3.md
diff --git a/docs/constitution/03_Cadre_Conformite_Label_Prestige.md b/docs/gouvernance/03_Cadre_Conformite_Label_Prestige.md
similarity index 100%
rename from docs/constitution/03_Cadre_Conformite_Label_Prestige.md
rename to docs/gouvernance/03_Cadre_Conformite_Label_Prestige.md
diff --git a/docs/constitution/Registraire des entreprises - Reçu de paiement.pdf b/docs/gouvernance/Registraire des entreprises - Reçu de paiement.pdf
similarity index 100%
rename from docs/constitution/Registraire des entreprises - Reçu de paiement.pdf
rename to docs/gouvernance/Registraire des entreprises - Reçu de paiement.pdf
diff --git a/docs/engineering/git-conventions.md b/docs/guides/engineering/git-conventions.md
similarity index 100%
rename from docs/engineering/git-conventions.md
rename to docs/guides/engineering/git-conventions.md
diff --git a/docs/00_Glossaire_biomimetique_autopoietique_v3.md b/docs/modele/00_Glossaire_biomimetique_autopoietique_v3.md
similarity index 100%
rename from docs/00_Glossaire_biomimetique_autopoietique_v3.md
rename to docs/modele/00_Glossaire_biomimetique_autopoietique_v3.md
diff --git a/docs/00_Modele_8_couches_biomimetique_autopoietique_v3.md b/docs/modele/00_Modele_8_couches_biomimetique_autopoietique_v3.md
similarity index 100%
rename from docs/00_Modele_8_couches_biomimetique_autopoietique_v3.md
rename to docs/modele/00_Modele_8_couches_biomimetique_autopoietique_v3.md
diff --git a/docs/00_Nomenclature_v4.md b/docs/modele/00_Nomenclature_v4.md
similarity index 100%
rename from docs/00_Nomenclature_v4.md
rename to docs/modele/00_Nomenclature_v4.md
diff --git a/docs/06 - Controles_Conformite_Label_Prestige_par_Couche_v1.0.md b/docs/politiques/06-Controles_Conformite_Label_Prestige_par_Couche_v1.0.md
similarity index 100%
rename from docs/06 - Controles_Conformite_Label_Prestige_par_Couche_v1.0.md
rename to docs/politiques/06-Controles_Conformite_Label_Prestige_par_Couche_v1.0.md
diff --git a/docs/pile opérateur/pol/POL-OBS-LOG-001 — Contrat de journalisation (Logs) — Référence Loki.md b/docs/politiques/POL-OBS-LOG-001 — Contrat de journalisation (Logs) — Référence Loki.md
similarity index 100%
rename from docs/pile opérateur/pol/POL-OBS-LOG-001 — Contrat de journalisation (Logs) — Référence Loki.md
rename to docs/politiques/POL-OBS-LOG-001 — Contrat de journalisation (Logs) — Référence Loki.md
diff --git a/docs/pile opérateur/pol/POL-OPS-STACK-001 — Conformité pile opérateur (C1–C5).md b/docs/politiques/POL-OPS-STACK-001 — Conformité pile opérateur (C1–C5).md
similarity index 100%
rename from docs/pile opérateur/pol/POL-OPS-STACK-001 — Conformité pile opérateur (C1–C5).md
rename to docs/politiques/POL-OPS-STACK-001 — Conformité pile opérateur (C1–C5).md
diff --git a/infrastructure/README.md b/infrastructure/README.md
new file mode 100644
index 0000000..567e6fb
--- /dev/null
+++ b/infrastructure/README.md
@@ -0,0 +1,9 @@
+# Infrastructure
+
+Contient l'implémentation opératoire :
+- ansible
+- opentofu
+- cloud-init
+- templates
+- netbox
+
diff --git a/infrastructure/ansible/.gitignore b/infrastructure/ansible/.gitignore
new file mode 100644
index 0000000..7eaa6e2
--- /dev/null
+++ b/infrastructure/ansible/.gitignore
@@ -0,0 +1,2 @@
+*.retry
+.ansible/
diff --git a/infrastructure/ansible/README.md b/infrastructure/ansible/README.md
new file mode 100644
index 0000000..ec5ae06
--- /dev/null
+++ b/infrastructure/ansible/README.md
@@ -0,0 +1,57 @@
+# ansible/
+
+Sous-arbre Ansible de l'Alliance Boréale pour la **mise en conformité post-provisionnement** des VMs.
+
+## Responsabilités
+
+Ce sous-arbre prend des VMs déjà créées et accessibles en SSH, puis applique :
+- la baseline packages commune ;
+- le hardening OS ;
+- le pare-feu local ;
+- les mises à jour de sécurité automatiques ;
+- l'agent Icinga2 ;
+- l'agent Wazuh en option.
+
+## Hors périmètre
+
+Ne relèvent **pas** de ce sous-arbre :
+- la création des VMs ;
+- le clonage de templates ;
+- la gestion Proxmox ;
+- la génération initiale des ressources cloud-init.
+
+Ces responsabilités appartiennent au sous-arbre `opentofu/` du dépôt principal.
+
+## Structure
+
+```text
+ansible/
+├── ansible.cfg
+├── requirements.yml
+├── inventories/prod/
+│ ├── hosts.yml
+│ ├── group_vars/all.yml
+│ └── host_vars/
+├── playbooks/
+│ ├── site.yml
+│ ├── baseline.yml
+│ └── hardening.yml
+├── roles/
+│ ├── baseline_common/
+│ ├── hardening_common/
+│ ├── firewall_nftables/
+│ ├── monitoring_icinga_agent/
+│ └── security_wazuh_agent/
+└── docs/
+```
+
+## Démarrage
+
+1. Laisser OpenTofu générer `inventories/prod/hosts.yml`.
+2. Ajuster `inventories/prod/group_vars/all.yml`.
+3. Vérifier les réseaux d'administration autorisés dans le firewall.
+4. Lancer :
+
+```bash
+ansible-playbook playbooks/site.yml
+```
diff --git a/infrastructure/ansible/ansible.cfg b/infrastructure/ansible/ansible.cfg
new file mode 100644
index 0000000..062b90f
--- /dev/null
+++ b/infrastructure/ansible/ansible.cfg
@@ -0,0 +1,18 @@
+[defaults]
+inventory = inventories/prod/hosts.yml
+roles_path = roles
+host_key_checking = False
+retry_files_enabled = False
+interpreter_python = auto_silent
+stdout_callback = yaml
+bin_ansible_callbacks = True
+timeout = 30
+forks = 20
+gathering = smart
+fact_caching = jsonfile
+fact_caching_connection = .ansible/facts
+fact_caching_timeout = 7200
+
+[ssh_connection]
+pipelining = True
+scp_if_ssh = True
diff --git a/infrastructure/ansible/docs/CONVERGENCE_NOTES.md b/infrastructure/ansible/docs/CONVERGENCE_NOTES.md
new file mode 100644
index 0000000..2563421
--- /dev/null
+++ b/infrastructure/ansible/docs/CONVERGENCE_NOTES.md
@@ -0,0 +1,33 @@
+# Rapport de convergence — sous-arbre ansible/
+
+## Décision d'architecture
+
+Le dépôt Ansible fusionné a été recentré pour jouer un rôle unique :
+**configurer et durcir des VMs déjà provisionnées**.
+
+La création des VMs, le template Debian 12, le clonage et l'écriture de l'inventaire relèvent désormais du dépôt OpenTofu.
+
+## Ce qui a été retenu
+
+- `baseline_common`
+- `hardening_common`
+- `firewall_nftables`
+- `monitoring_icinga_agent`
+- `security_wazuh_agent`
+- inventaire YAML simple
+- playbooks séparés `baseline`, `hardening`, `site`
+
+## Ce qui a été retiré du chemin principal
+
+- `proxmox_debian12_template`
+- `proxmox_vm_clone`
+- `playbooks/proxmox/*`
+
+## Logique cible
+
+Le sous-arbre `ansible/` vise une baseline VM commune :
+1. petite ;
+2. reproductible ;
+3. fermée par défaut ;
+4. compatible avec l'inventaire généré par OpenTofu ;
+5. prête à recevoir ensuite les rôles applicatifs C2/C3/C4/C5.
diff --git a/infrastructure/ansible/inventories/prod/group_vars/all.yml b/infrastructure/ansible/inventories/prod/group_vars/all.yml
new file mode 100644
index 0000000..1d288ca
--- /dev/null
+++ b/infrastructure/ansible/inventories/prod/group_vars/all.yml
@@ -0,0 +1,86 @@
+---
+# Paramètres globaux de la baseline commune Alliance Boréale
+
+ab_domain: example.internal
+ab_dns_servers:
+ - 192.0.2.10
+ - 192.0.2.20
+ab_admin_networks:
+ - 192.0.2.0/24
+ab_ntp_server: c2-opnsense-01.example.internal
+ab_ansible_user: ansible
+ab_ansible_ssh_key_path: ~/.ssh/id_ed25519_ansible
+ab_timezone: America/Montreal
+ab_enable_wazuh_agent: false
+
+ansible_user: "{{ ab_ansible_user }}"
+ansible_ssh_private_key_file: "{{ ab_ansible_ssh_key_path }}"
+
+# Baseline commune
+baseline_common_enabled: true
+baseline_common_upgrade: true
+baseline_common_remove_packages: []
+baseline_common_packages:
+ - apt-listchanges
+ - unattended-upgrades
+ - needrestart
+ - debsecan
+ - ca-certificates
+ - curl
+ - jq
+ - vim
+ - less
+ - git
+ - sudo
+ - rsync
+ - python3
+ - python3-apt
+ - acl
+ - chrony
+ - qemu-guest-agent
+ - nftables
+ - apparmor
+ - apparmor-utils
+ - fail2ban
+ - debian-archive-keyring
+
+a_baseline_common_manage_sources: false
+
+# Hardening commun
+hardening_common_enabled: true
+hardening_common_fail2ban_enabled: true
+hardening_common_unattended_upgrades_enabled: true
+hardening_common_debsecan_enabled: true
+hardening_common_apparmor_enabled: true
+hardening_common_journald_enabled: true
+hardening_common_journald_system_max_use: 512M
+hardening_common_journald_runtime_max_use: 128M
+hardening_common_ssh_port: 22
+hardening_common_ssh_allow_groups:
+ - sudo
+hardening_common_ssh_listen_addresses: []
+hardening_common_fail2ban_sshd_enabled: true
+
+# Pare-feu local
+firewall_nftables_enabled: true
+firewall_nftables_allow_ipv6: true
+firewall_nftables_policy_input: drop
+firewall_nftables_policy_forward: drop
+firewall_nftables_policy_output: accept
+firewall_nftables_allowed_tcp_in:
+ - dport: 22
+ src: 192.0.2.0/24
+firewall_nftables_allowed_udp_in: []
+firewall_nftables_allow_icmp: true
+
+# Monitoring commun
+monitoring_icinga_agent_enabled: true
+monitoring_icinga_agent_master: c3-icinga-01.example.internal
+monitoring_icinga_agent_parent_zone: master
+monitoring_icinga_agent_zone: "{{ inventory_hostname }}"
+
+# Wazuh optionnel
+security_wazuh_agent_enabled: "{{ ab_enable_wazuh_agent }}"
+security_wazuh_agent_manager: c3-wazuh-01.example.internal
+security_wazuh_agent_registration_password: ""
+
diff --git a/infrastructure/ansible/inventories/prod/hosts.yml b/infrastructure/ansible/inventories/prod/hosts.yml
new file mode 100644
index 0000000..c898d35
--- /dev/null
+++ b/infrastructure/ansible/inventories/prod/hosts.yml
@@ -0,0 +1,4 @@
+all:
+ children:
+ boreale_all:
+ hosts: {}
diff --git a/infrastructure/ansible/playbooks/baseline.yml b/infrastructure/ansible/playbooks/baseline.yml
new file mode 100644
index 0000000..8eac6be
--- /dev/null
+++ b/infrastructure/ansible/playbooks/baseline.yml
@@ -0,0 +1,6 @@
+---
+- name: Baseline packages et services communs
+ hosts: boreale_all
+ become: true
+ roles:
+ - role: baseline_common
diff --git a/infrastructure/ansible/playbooks/hardening.yml b/infrastructure/ansible/playbooks/hardening.yml
new file mode 100644
index 0000000..47ea76d
--- /dev/null
+++ b/infrastructure/ansible/playbooks/hardening.yml
@@ -0,0 +1,9 @@
+---
+- name: Hardening commun Alliance Boréale
+ hosts: boreale_all
+ become: true
+ roles:
+ - role: hardening_common
+ - role: firewall_nftables
+ - role: monitoring_icinga_agent
+ - role: security_wazuh_agent
diff --git a/infrastructure/ansible/playbooks/site.yml b/infrastructure/ansible/playbooks/site.yml
new file mode 100644
index 0000000..c307369
--- /dev/null
+++ b/infrastructure/ansible/playbooks/site.yml
@@ -0,0 +1,10 @@
+---
+- name: Baseline complète Alliance Boréale
+ hosts: boreale_all
+ become: true
+ roles:
+ - role: baseline_common
+ - role: hardening_common
+ - role: firewall_nftables
+ - role: monitoring_icinga_agent
+ - role: security_wazuh_agent
diff --git a/infrastructure/ansible/requirements.yml b/infrastructure/ansible/requirements.yml
new file mode 100644
index 0000000..92a0244
--- /dev/null
+++ b/infrastructure/ansible/requirements.yml
@@ -0,0 +1,4 @@
+---
+collections:
+ - name: ansible.posix
+ - name: community.general
diff --git a/infrastructure/ansible/roles/baseline_common/defaults/main.yml b/infrastructure/ansible/roles/baseline_common/defaults/main.yml
new file mode 100644
index 0000000..c79cf4e
--- /dev/null
+++ b/infrastructure/ansible/roles/baseline_common/defaults/main.yml
@@ -0,0 +1,8 @@
+---
+baseline_common_enabled: true
+baseline_common_upgrade: true
+baseline_common_packages: []
+baseline_common_remove_packages: []
+baseline_common_manage_chrony: true
+baseline_common_manage_timezone: true
+baseline_common_qemu_guest_agent_service: qemu-guest-agent
diff --git a/infrastructure/ansible/roles/baseline_common/handlers/main.yml b/infrastructure/ansible/roles/baseline_common/handlers/main.yml
new file mode 100644
index 0000000..52e5605
--- /dev/null
+++ b/infrastructure/ansible/roles/baseline_common/handlers/main.yml
@@ -0,0 +1,12 @@
+---
+- name: Restart chrony
+ ansible.builtin.systemd:
+ name: chrony
+ state: restarted
+
+- name: Restart systemd-timesyncd if present
+ ansible.builtin.systemd:
+ name: systemd-timesyncd
+ state: stopped
+ enabled: false
+ failed_when: false
diff --git a/infrastructure/ansible/roles/baseline_common/tasks/main.yml b/infrastructure/ansible/roles/baseline_common/tasks/main.yml
new file mode 100644
index 0000000..1e8509c
--- /dev/null
+++ b/infrastructure/ansible/roles/baseline_common/tasks/main.yml
@@ -0,0 +1,61 @@
+---
+- name: Gate
+ ansible.builtin.meta: end_host
+ when: not baseline_common_enabled | bool
+
+- name: Mettre à jour le cache APT
+ ansible.builtin.apt:
+ update_cache: true
+ cache_valid_time: 3600
+
+- name: Installer les paquets communs
+ ansible.builtin.apt:
+ name: "{{ baseline_common_packages }}"
+ state: present
+
+- name: Retirer les paquets explicitement exclus
+ ansible.builtin.apt:
+ name: "{{ baseline_common_remove_packages }}"
+ state: absent
+ purge: true
+ when: baseline_common_remove_packages | length > 0
+
+- name: Appliquer les mises à jour de distribution
+ ansible.builtin.apt:
+ upgrade: dist
+ when: baseline_common_upgrade | bool
+
+- name: Régler le fuseau horaire
+ community.general.timezone:
+ name: "{{ ab_timezone }}"
+ when: baseline_common_manage_timezone | bool
+
+- name: Désactiver systemd-timesyncd si présent
+ ansible.builtin.systemd:
+ name: systemd-timesyncd
+ enabled: false
+ state: stopped
+ failed_when: false
+ when: baseline_common_manage_chrony | bool
+
+- name: Déployer la configuration chrony
+ ansible.builtin.template:
+ src: chrony.conf.j2
+ dest: /etc/chrony/chrony.conf
+ mode: '0644'
+ when: baseline_common_manage_chrony | bool
+ notify: Restart chrony
+
+- name: Activer chrony
+ ansible.builtin.systemd:
+ name: chrony
+ enabled: true
+ state: started
+ when: baseline_common_manage_chrony | bool
+
+- name: Activer qemu-guest-agent si présent
+ ansible.builtin.systemd:
+ name: "{{ baseline_common_qemu_guest_agent_service }}"
+ enabled: true
+ state: started
+ failed_when: false
diff --git a/infrastructure/ansible/roles/baseline_common/templates/chrony.conf.j2 b/infrastructure/ansible/roles/baseline_common/templates/chrony.conf.j2
new file mode 100644
index 0000000..402db33
--- /dev/null
+++ b/infrastructure/ansible/roles/baseline_common/templates/chrony.conf.j2
@@ -0,0 +1,12 @@
+# Ansible managed: baseline_common
+
+pool 2.debian.pool.ntp.org iburst maxsources 2
+server {{ ab_ntp_server }} iburst prefer
+{% for dns in ab_dns_servers | default([]) %}
+# DNS interne disponible: {{ dns }}
+{% endfor %}
+
+driftfile /var/lib/chrony/chrony.drift
+rtcsync
+makestep 1 3
+logdir /var/log/chrony
diff --git a/infrastructure/ansible/roles/firewall_nftables/defaults/main.yml b/infrastructure/ansible/roles/firewall_nftables/defaults/main.yml
new file mode 100644
index 0000000..c15c217
--- /dev/null
+++ b/infrastructure/ansible/roles/firewall_nftables/defaults/main.yml
@@ -0,0 +1,9 @@
+---
+firewall_nftables_enabled: true
+firewall_nftables_allow_ipv6: true
+firewall_nftables_allow_icmp: true
+firewall_nftables_policy_input: drop
+firewall_nftables_policy_forward: drop
+firewall_nftables_policy_output: accept
+firewall_nftables_allowed_tcp_in: []
+firewall_nftables_allowed_udp_in: []
diff --git a/infrastructure/ansible/roles/firewall_nftables/handlers/main.yml b/infrastructure/ansible/roles/firewall_nftables/handlers/main.yml
new file mode 100644
index 0000000..69e8f72
--- /dev/null
+++ b/infrastructure/ansible/roles/firewall_nftables/handlers/main.yml
@@ -0,0 +1,5 @@
+---
+- name: Reload nftables
+ ansible.builtin.systemd:
+ name: nftables
+ state: reloaded
diff --git a/infrastructure/ansible/roles/firewall_nftables/tasks/main.yml b/infrastructure/ansible/roles/firewall_nftables/tasks/main.yml
new file mode 100644
index 0000000..3e36cce
--- /dev/null
+++ b/infrastructure/ansible/roles/firewall_nftables/tasks/main.yml
@@ -0,0 +1,23 @@
+---
+- name: Gate
+ ansible.builtin.meta: end_host
+ when: not firewall_nftables_enabled | bool
+
+- name: Installer nftables
+ ansible.builtin.apt:
+ name: nftables
+ state: present
+ update_cache: true
+
+- name: Déployer nftables
+ ansible.builtin.template:
+ src: nftables.conf.j2
+ dest: /etc/nftables.conf
+ mode: '0644'
+ notify: Reload nftables
+
+- name: Activer nftables
+ ansible.builtin.systemd:
+ name: nftables
+ enabled: true
+ state: started
diff --git a/infrastructure/ansible/roles/firewall_nftables/templates/nftables.conf.j2 b/infrastructure/ansible/roles/firewall_nftables/templates/nftables.conf.j2
new file mode 100644
index 0000000..e2edcdd
--- /dev/null
+++ b/infrastructure/ansible/roles/firewall_nftables/templates/nftables.conf.j2
@@ -0,0 +1,34 @@
+#!/usr/sbin/nft -f
+flush ruleset
+
+table inet filter {
+ chain input {
+ type filter hook input priority 0;
+ policy {{ firewall_nftables_policy_input }};
+
+ iif lo accept
+ ct state established,related accept
+{% if firewall_nftables_allow_icmp %}
+ ip protocol icmp accept
+{% if firewall_nftables_allow_ipv6 %}
+ ip6 nexthdr icmpv6 accept
+{% endif %}
+{% endif %}
+{% for rule in firewall_nftables_allowed_tcp_in %}
+ tcp dport {{ rule.dport }} ip saddr {{ rule.src }} accept
+{% endfor %}
+{% for rule in firewall_nftables_allowed_udp_in %}
+ udp dport {{ rule.dport }} ip saddr {{ rule.src }} accept
+{% endfor %}
+ }
+
+ chain forward {
+ type filter hook forward priority 0;
+ policy {{ firewall_nftables_policy_forward }};
+ }
+
+ chain output {
+ type filter hook output priority 0;
+ policy {{ firewall_nftables_policy_output }};
+ }
+}
diff --git a/infrastructure/ansible/roles/hardening_common/defaults/main.yml b/infrastructure/ansible/roles/hardening_common/defaults/main.yml
new file mode 100644
index 0000000..f3765b2
--- /dev/null
+++ b/infrastructure/ansible/roles/hardening_common/defaults/main.yml
@@ -0,0 +1,58 @@
+---
+hardening_common_enabled: true
+hardening_common_fail2ban_enabled: true
+hardening_common_fail2ban_sshd_enabled: true
+hardening_common_unattended_upgrades_enabled: true
+hardening_common_debsecan_enabled: true
+hardening_common_apparmor_enabled: true
+hardening_common_journald_enabled: true
+hardening_common_journald_system_max_use: 512M
+hardening_common_journald_runtime_max_use: 128M
+hardening_common_ssh_port: 22
+hardening_common_ssh_allow_groups: []
+hardening_common_ssh_listen_addresses: []
+hardening_common_sysctl:
+ fs.protected_fifos: 2
+ fs.protected_hardlinks: 1
+ fs.protected_regular: 2
+ fs.protected_symlinks: 1
+ kernel.dmesg_restrict: 1
+ kernel.kptr_restrict: 2
+ kernel.randomize_va_space: 2
+ kernel.sysrq: 0
+ net.ipv4.conf.all.accept_redirects: 0
+ net.ipv4.conf.default.accept_redirects: 0
+ net.ipv4.conf.all.accept_source_route: 0
+ net.ipv4.conf.default.accept_source_route: 0
+ net.ipv4.conf.all.log_martians: 1
+ net.ipv4.conf.default.log_martians: 1
+ net.ipv4.conf.all.rp_filter: 1
+ net.ipv4.conf.default.rp_filter: 1
+ net.ipv4.conf.all.send_redirects: 0
+ net.ipv4.conf.default.send_redirects: 0
+ net.ipv4.icmp_echo_ignore_broadcasts: 1
+ net.ipv4.ip_forward: 0
+ net.ipv4.tcp_syncookies: 1
+ net.ipv6.conf.all.accept_redirects: 0
+ net.ipv6.conf.default.accept_redirects: 0
+ net.ipv6.conf.all.accept_source_route: 0
+ net.ipv6.conf.default.accept_source_route: 0
+hardening_common_sshd_settings:
+ PasswordAuthentication: 'no'
+ PermitRootLogin: 'no'
+ KbdInteractiveAuthentication: 'no'
+ ChallengeResponseAuthentication: 'no'
+ PubkeyAuthentication: 'yes'
+ X11Forwarding: 'no'
+ MaxAuthTries: '3'
+ LoginGraceTime: '30'
+ AllowAgentForwarding: 'no'
+ AllowTcpForwarding: 'no'
+ TCPKeepAlive: 'no'
+ ClientAliveInterval: '300'
+ ClientAliveCountMax: '2'
+ MaxSessions: '10'
+ MaxStartups: '10:30:60'
+ Protocol: '2'
+ Port: '22'
+ UsePAM: 'yes'
diff --git a/infrastructure/ansible/roles/hardening_common/handlers/main.yml b/infrastructure/ansible/roles/hardening_common/handlers/main.yml
new file mode 100644
index 0000000..b36f530
--- /dev/null
+++ b/infrastructure/ansible/roles/hardening_common/handlers/main.yml
@@ -0,0 +1,15 @@
+---
+- name: Reload ssh
+ ansible.builtin.systemd:
+ name: ssh
+ state: reloaded
+
+- name: Restart journald
+ ansible.builtin.systemd:
+ name: systemd-journald
+ state: restarted
+
+- name: Restart fail2ban
+ ansible.builtin.systemd:
+ name: fail2ban
+ state: restarted
diff --git a/infrastructure/ansible/roles/hardening_common/tasks/main.yml b/infrastructure/ansible/roles/hardening_common/tasks/main.yml
new file mode 100644
index 0000000..ecf082c
--- /dev/null
+++ b/infrastructure/ansible/roles/hardening_common/tasks/main.yml
@@ -0,0 +1,86 @@
+---
+- name: Gate
+ ansible.builtin.meta: end_host
+ when: not hardening_common_enabled | bool
+
+- name: Appliquer le socle sysctl
+ ansible.posix.sysctl:
+ name: "{{ item.key }}"
+ value: "{{ item.value }}"
+ state: present
+ sysctl_set: true
+ reload: true
+ loop: "{{ hardening_common_sysctl | dict2items }}"
+
+- name: Déployer le drop-in SSH durci
+ ansible.builtin.template:
+ src: sshd_boreale_hardening.conf.j2
+ dest: /etc/ssh/sshd_config.d/99-boreale-hardening.conf
+ mode: '0644'
+ validate: '/usr/sbin/sshd -T -f %s'
+ notify: Reload ssh
+
+- name: Déployer le drop-in journald
+ ansible.builtin.template:
+ src: journald-boreale.conf.j2
+ dest: /etc/systemd/journald.conf.d/99-boreale.conf
+ mode: '0644'
+ when: hardening_common_journald_enabled | bool
+ notify: Restart journald
+
+- name: Installer fail2ban
+ ansible.builtin.apt:
+ name: fail2ban
+ state: present
+ when: hardening_common_fail2ban_enabled | bool
+
+- name: Déployer la jail sshd fail2ban
+ ansible.builtin.template:
+ src: jail-sshd.local.j2
+ dest: /etc/fail2ban/jail.d/sshd.local
+ mode: '0644'
+ when:
+ - hardening_common_fail2ban_enabled | bool
+ - hardening_common_fail2ban_sshd_enabled | bool
+ notify: Restart fail2ban
+
+- name: Activer fail2ban
+ ansible.builtin.systemd:
+ name: fail2ban
+ enabled: true
+ state: started
+ when: hardening_common_fail2ban_enabled | bool
+
+- name: Déployer unattended-upgrades auto
+ ansible.builtin.copy:
+ dest: /etc/apt/apt.conf.d/20auto-upgrades
+ mode: '0644'
+ content: |
+ APT::Periodic::Update-Package-Lists "1";
+ APT::Periodic::Unattended-Upgrade "1";
+ APT::Periodic::AutocleanInterval "7";
+ when: hardening_common_unattended_upgrades_enabled | bool
+
+- name: Déployer unattended-upgrades de base
+ ansible.builtin.copy:
+ dest: /etc/apt/apt.conf.d/52unattended-upgrades-local
+ mode: '0644'
+ content: |
+ Unattended-Upgrade::Remove-Unused-Dependencies "true";
+ Unattended-Upgrade::Automatic-Reboot "false";
+ Unattended-Upgrade::Automatic-Reboot-WithUsers "false";
+ when: hardening_common_unattended_upgrades_enabled | bool
+
+- name: Installer debsecan
+ ansible.builtin.apt:
+ name: debsecan
+ state: present
+ when: hardening_common_debsecan_enabled | bool
+
+- name: Activer AppArmor
+ ansible.builtin.systemd:
+ name: apparmor
+ enabled: true
+ state: started
+ failed_when: false
+ when: hardening_common_apparmor_enabled | bool
diff --git a/infrastructure/ansible/roles/hardening_common/templates/jail-sshd.local.j2 b/infrastructure/ansible/roles/hardening_common/templates/jail-sshd.local.j2
new file mode 100644
index 0000000..81eec90
--- /dev/null
+++ b/infrastructure/ansible/roles/hardening_common/templates/jail-sshd.local.j2
@@ -0,0 +1,7 @@
+[sshd]
+enabled = true
+port = {{ hardening_common_ssh_port }}
+backend = systemd
+maxretry = 4
+findtime = 10m
+bantime = 1h
diff --git a/infrastructure/ansible/roles/hardening_common/templates/journald-boreale.conf.j2 b/infrastructure/ansible/roles/hardening_common/templates/journald-boreale.conf.j2
new file mode 100644
index 0000000..e3276cf
--- /dev/null
+++ b/infrastructure/ansible/roles/hardening_common/templates/journald-boreale.conf.j2
@@ -0,0 +1,6 @@
+[Journal]
+Storage=persistent
+Compress=yes
+SystemMaxUse={{ hardening_common_journald_system_max_use }}
+RuntimeMaxUse={{ hardening_common_journald_runtime_max_use }}
+ForwardToSyslog=no
diff --git a/infrastructure/ansible/roles/hardening_common/templates/sshd_boreale_hardening.conf.j2 b/infrastructure/ansible/roles/hardening_common/templates/sshd_boreale_hardening.conf.j2
new file mode 100644
index 0000000..d71be7c
--- /dev/null
+++ b/infrastructure/ansible/roles/hardening_common/templates/sshd_boreale_hardening.conf.j2
@@ -0,0 +1,14 @@
+# Ansible managed: hardening_common
+{% for address in hardening_common_ssh_listen_addresses %}
+ListenAddress {{ address }}
+{% endfor %}
+{% for key, value in hardening_common_sshd_settings.items() %}
+{% if key == 'Port' %}
+Port {{ hardening_common_ssh_port }}
+{% else %}
+{{ key }} {{ value }}
+{% endif %}
+{% endfor %}
+{% if hardening_common_ssh_allow_groups | length > 0 %}
+AllowGroups {{ hardening_common_ssh_allow_groups | join(' ') }}
+{% endif %}
diff --git a/infrastructure/ansible/roles/monitoring_icinga_agent/defaults/main.yml b/infrastructure/ansible/roles/monitoring_icinga_agent/defaults/main.yml
new file mode 100644
index 0000000..9108763
--- /dev/null
+++ b/infrastructure/ansible/roles/monitoring_icinga_agent/defaults/main.yml
@@ -0,0 +1,7 @@
+---
+monitoring_icinga_agent_enabled: true
+monitoring_icinga_agent_pkg: icinga2
+monitoring_icinga_agent_service: icinga2
+monitoring_icinga_agent_master: ''
+monitoring_icinga_agent_parent_zone: master
+monitoring_icinga_agent_zone: '{{ inventory_hostname }}'
diff --git a/infrastructure/ansible/roles/monitoring_icinga_agent/handlers/main.yml b/infrastructure/ansible/roles/monitoring_icinga_agent/handlers/main.yml
new file mode 100644
index 0000000..bdd5df3
--- /dev/null
+++ b/infrastructure/ansible/roles/monitoring_icinga_agent/handlers/main.yml
@@ -0,0 +1,5 @@
+---
+- name: Restart icinga2
+ ansible.builtin.systemd:
+ name: icinga2
+ state: restarted
diff --git a/infrastructure/ansible/roles/monitoring_icinga_agent/tasks/main.yml b/infrastructure/ansible/roles/monitoring_icinga_agent/tasks/main.yml
new file mode 100644
index 0000000..09f7d32
--- /dev/null
+++ b/infrastructure/ansible/roles/monitoring_icinga_agent/tasks/main.yml
@@ -0,0 +1,24 @@
+---
+- name: Gate
+ ansible.builtin.meta: end_host
+ when: not monitoring_icinga_agent_enabled | bool
+
+- name: Installer l'agent Icinga2
+ ansible.builtin.apt:
+ name: '{{ monitoring_icinga_agent_pkg }}'
+ state: present
+ update_cache: true
+
+- name: Déployer zones.conf minimal
+ ansible.builtin.template:
+ src: zones.conf.j2
+ dest: /etc/icinga2/zones.conf
+ mode: '0644'
+ when: monitoring_icinga_agent_master | length > 0
+ notify: Restart icinga2
+
+- name: Activer l'agent Icinga2
+ ansible.builtin.systemd:
+ name: '{{ monitoring_icinga_agent_service }}'
+ enabled: true
+ state: started
diff --git a/infrastructure/ansible/roles/monitoring_icinga_agent/templates/zones.conf.j2 b/infrastructure/ansible/roles/monitoring_icinga_agent/templates/zones.conf.j2
new file mode 100644
index 0000000..ebdedaf
--- /dev/null
+++ b/infrastructure/ansible/roles/monitoring_icinga_agent/templates/zones.conf.j2
@@ -0,0 +1,15 @@
+// Ansible managed: monitoring_icinga_agent
+object Endpoint "{{ monitoring_icinga_agent_master }}" {
+ host = "{{ monitoring_icinga_agent_master }}"
+}
+
+object Zone "{{ monitoring_icinga_agent_parent_zone }}" {
+ endpoints = [ "{{ monitoring_icinga_agent_master }}" ]
+}
+
+object Endpoint "{{ monitoring_icinga_agent_zone }}" {}
+
+object Zone "{{ monitoring_icinga_agent_zone }}" {
+ endpoints = [ "{{ monitoring_icinga_agent_zone }}" ]
+ parent = "{{ monitoring_icinga_agent_parent_zone }}"
+}
diff --git a/infrastructure/ansible/roles/security_wazuh_agent/defaults/main.yml b/infrastructure/ansible/roles/security_wazuh_agent/defaults/main.yml
new file mode 100644
index 0000000..d6dc35f
--- /dev/null
+++ b/infrastructure/ansible/roles/security_wazuh_agent/defaults/main.yml
@@ -0,0 +1,4 @@
+---
+security_wazuh_agent_enabled: false
+security_wazuh_agent_manager: ''
+security_wazuh_agent_registration_password: ''
diff --git a/infrastructure/ansible/roles/security_wazuh_agent/handlers/main.yml b/infrastructure/ansible/roles/security_wazuh_agent/handlers/main.yml
new file mode 100644
index 0000000..6ff2284
--- /dev/null
+++ b/infrastructure/ansible/roles/security_wazuh_agent/handlers/main.yml
@@ -0,0 +1,5 @@
+---
+- name: Restart wazuh-agent
+ ansible.builtin.systemd:
+ name: wazuh-agent
+ state: restarted
diff --git a/infrastructure/ansible/roles/security_wazuh_agent/tasks/main.yml b/infrastructure/ansible/roles/security_wazuh_agent/tasks/main.yml
new file mode 100644
index 0000000..8445a6a
--- /dev/null
+++ b/infrastructure/ansible/roles/security_wazuh_agent/tasks/main.yml
@@ -0,0 +1,26 @@
+---
+- name: Gate
+ ansible.builtin.meta: end_host
+ when: not security_wazuh_agent_enabled | bool
+
+- name: Installer l'agent Wazuh depuis APT natif si disponible
+ ansible.builtin.apt:
+ name: wazuh-agent
+ state: present
+ update_cache: true
+ failed_when: false
+
+- name: Déployer ossec.conf minimal
+ ansible.builtin.template:
+ src: ossec.conf.j2
+ dest: /var/ossec/etc/ossec.conf
+ mode: '0640'
+ when: security_wazuh_agent_manager | length > 0
+ notify: Restart wazuh-agent
+
+- name: Activer l'agent Wazuh
+ ansible.builtin.systemd:
+ name: wazuh-agent
+ enabled: true
+ state: started
+ failed_when: false
diff --git a/infrastructure/ansible/roles/security_wazuh_agent/templates/ossec.conf.j2 b/infrastructure/ansible/roles/security_wazuh_agent/templates/ossec.conf.j2
new file mode 100644
index 0000000..a6ba33d
--- /dev/null
+++ b/infrastructure/ansible/roles/security_wazuh_agent/templates/ossec.conf.j2
@@ -0,0 +1,13 @@
+
+
+
+ {{ security_wazuh_agent_manager }}
+ 1514
+ tcp
+
+ 10
+ 60
+ yes
+ aes
+
+
diff --git a/ansible/README-PHASE2.md b/infrastructure/ansible2/README-PHASE2.md
similarity index 100%
rename from ansible/README-PHASE2.md
rename to infrastructure/ansible2/README-PHASE2.md
diff --git a/ansible/README.md b/infrastructure/ansible2/README.md
similarity index 100%
rename from ansible/README.md
rename to infrastructure/ansible2/README.md
diff --git a/ansible/ansible.cfg b/infrastructure/ansible2/ansible.cfg
similarity index 100%
rename from ansible/ansible.cfg
rename to infrastructure/ansible2/ansible.cfg
diff --git a/ansible/devis phases 2.5 et 3.md b/infrastructure/ansible2/devis phases 2.5 et 3.md
similarity index 100%
rename from ansible/devis phases 2.5 et 3.md
rename to infrastructure/ansible2/devis phases 2.5 et 3.md
diff --git a/ansible/inventories/production/group_vars/all.yml b/infrastructure/ansible2/inventories/production/group_vars/all.yml
similarity index 100%
rename from ansible/inventories/production/group_vars/all.yml
rename to infrastructure/ansible2/inventories/production/group_vars/all.yml
diff --git a/ansible/inventories/production/group_vars/dns_servers.yml b/infrastructure/ansible2/inventories/production/group_vars/dns_servers.yml
similarity index 100%
rename from ansible/inventories/production/group_vars/dns_servers.yml
rename to infrastructure/ansible2/inventories/production/group_vars/dns_servers.yml
diff --git a/ansible/inventories/production/group_vars/forge_servers.yml b/infrastructure/ansible2/inventories/production/group_vars/forge_servers.yml
similarity index 100%
rename from ansible/inventories/production/group_vars/forge_servers.yml
rename to infrastructure/ansible2/inventories/production/group_vars/forge_servers.yml
diff --git a/ansible/inventories/production/group_vars/idp_servers.yml b/infrastructure/ansible2/inventories/production/group_vars/idp_servers.yml
similarity index 100%
rename from ansible/inventories/production/group_vars/idp_servers.yml
rename to infrastructure/ansible2/inventories/production/group_vars/idp_servers.yml
diff --git a/ansible/inventories/production/hosts.yml b/infrastructure/ansible2/inventories/production/hosts.yml
similarity index 100%
rename from ansible/inventories/production/hosts.yml
rename to infrastructure/ansible2/inventories/production/hosts.yml
diff --git a/infrastructure/ansible2/inventory/tofu_generated.yml b/infrastructure/ansible2/inventory/tofu_generated.yml
new file mode 100644
index 0000000..7876d5c
--- /dev/null
+++ b/infrastructure/ansible2/inventory/tofu_generated.yml
@@ -0,0 +1,33 @@
+# ══════════════════════════════════════════════════════════════════
+# Inventaire Ansible — généré par OpenTofu
+# NE PAS MODIFIER MANUELLEMENT — regénéré à chaque tofu apply
+# ══════════════════════════════════════════════════════════════════
+---
+"all":
+ "children":
+ "c3_monitoring":
+ "hosts":
+ "c3-icinga-01":
+ "ansible_host": "192.168.10.31"
+ "icinga_role": "master"
+ "c3_services":
+ "hosts":
+ "c3-netbox-01":
+ "ansible_host": "192.168.10.30"
+ "c4_forge":
+ "hosts":
+ "c4-forgejo-01":
+ "ansible_host": "192.168.10.40"
+ "c5_runner":
+ "hosts":
+ "c5-runner-01":
+ "ansible_host": "192.168.10.50"
+ "c7_tenants":
+ "hosts":
+ "c7-87-16-01":
+ "ansible_host": "192.168.12.45"
+ "c7-life-noc-01":
+ "ansible_host": "192.168.12.40"
+ "vars":
+ "ansible_ssh_private_key_file": "~/.ssh/id_ed25519_ansible_chezlepro"
+ "ansible_user": "ansible"
diff --git a/ansible/playbooks/phase1-dns-deploy.yml b/infrastructure/ansible2/playbooks/phase1-dns-deploy.yml
similarity index 100%
rename from ansible/playbooks/phase1-dns-deploy.yml
rename to infrastructure/ansible2/playbooks/phase1-dns-deploy.yml
diff --git a/ansible/playbooks/phase2-deploy.yml b/infrastructure/ansible2/playbooks/phase2-deploy.yml
similarity index 100%
rename from ansible/playbooks/phase2-deploy.yml
rename to infrastructure/ansible2/playbooks/phase2-deploy.yml
diff --git a/ansible/roles/common/defaults/main.yml b/infrastructure/ansible2/roles/common/defaults/main.yml
similarity index 100%
rename from ansible/roles/common/defaults/main.yml
rename to infrastructure/ansible2/roles/common/defaults/main.yml
diff --git a/ansible/roles/common/handlers/main.yml b/infrastructure/ansible2/roles/common/handlers/main.yml
similarity index 100%
rename from ansible/roles/common/handlers/main.yml
rename to infrastructure/ansible2/roles/common/handlers/main.yml
diff --git a/ansible/roles/common/tasks/logging.yml b/infrastructure/ansible2/roles/common/tasks/logging.yml
similarity index 100%
rename from ansible/roles/common/tasks/logging.yml
rename to infrastructure/ansible2/roles/common/tasks/logging.yml
diff --git a/ansible/roles/common/tasks/main.yml b/infrastructure/ansible2/roles/common/tasks/main.yml
similarity index 100%
rename from ansible/roles/common/tasks/main.yml
rename to infrastructure/ansible2/roles/common/tasks/main.yml
diff --git a/ansible/roles/common/tasks/nftables.yml b/infrastructure/ansible2/roles/common/tasks/nftables.yml
similarity index 100%
rename from ansible/roles/common/tasks/nftables.yml
rename to infrastructure/ansible2/roles/common/tasks/nftables.yml
diff --git a/ansible/roles/common/tasks/ntp.yml b/infrastructure/ansible2/roles/common/tasks/ntp.yml
similarity index 100%
rename from ansible/roles/common/tasks/ntp.yml
rename to infrastructure/ansible2/roles/common/tasks/ntp.yml
diff --git a/ansible/roles/common/tasks/security.yml b/infrastructure/ansible2/roles/common/tasks/security.yml
similarity index 100%
rename from ansible/roles/common/tasks/security.yml
rename to infrastructure/ansible2/roles/common/tasks/security.yml
diff --git a/ansible/roles/common/tasks/ssh.yml b/infrastructure/ansible2/roles/common/tasks/ssh.yml
similarity index 100%
rename from ansible/roles/common/tasks/ssh.yml
rename to infrastructure/ansible2/roles/common/tasks/ssh.yml
diff --git a/ansible/roles/common/templates/chrony.conf.j2 b/infrastructure/ansible2/roles/common/templates/chrony.conf.j2
similarity index 100%
rename from ansible/roles/common/templates/chrony.conf.j2
rename to infrastructure/ansible2/roles/common/templates/chrony.conf.j2
diff --git a/ansible/roles/common/templates/nftables.conf.j2 b/infrastructure/ansible2/roles/common/templates/nftables.conf.j2
similarity index 100%
rename from ansible/roles/common/templates/nftables.conf.j2
rename to infrastructure/ansible2/roles/common/templates/nftables.conf.j2
diff --git a/ansible/roles/common/templates/sshd.conf.j2 b/infrastructure/ansible2/roles/common/templates/sshd.conf.j2
similarity index 100%
rename from ansible/roles/common/templates/sshd.conf.j2
rename to infrastructure/ansible2/roles/common/templates/sshd.conf.j2
diff --git a/ansible/roles/forgejo/handlers/main.yml b/infrastructure/ansible2/roles/forgejo/handlers/main.yml
similarity index 100%
rename from ansible/roles/forgejo/handlers/main.yml
rename to infrastructure/ansible2/roles/forgejo/handlers/main.yml
diff --git a/ansible/roles/forgejo/tasks/database.yml b/infrastructure/ansible2/roles/forgejo/tasks/database.yml
similarity index 100%
rename from ansible/roles/forgejo/tasks/database.yml
rename to infrastructure/ansible2/roles/forgejo/tasks/database.yml
diff --git a/ansible/roles/forgejo/tasks/main.yml b/infrastructure/ansible2/roles/forgejo/tasks/main.yml
similarity index 100%
rename from ansible/roles/forgejo/tasks/main.yml
rename to infrastructure/ansible2/roles/forgejo/tasks/main.yml
diff --git a/ansible/roles/forgejo/templates/app.ini.j2 b/infrastructure/ansible2/roles/forgejo/templates/app.ini.j2
similarity index 100%
rename from ansible/roles/forgejo/templates/app.ini.j2
rename to infrastructure/ansible2/roles/forgejo/templates/app.ini.j2
diff --git a/ansible/roles/forgejo/templates/forgejo.service.j2 b/infrastructure/ansible2/roles/forgejo/templates/forgejo.service.j2
similarity index 100%
rename from ansible/roles/forgejo/templates/forgejo.service.j2
rename to infrastructure/ansible2/roles/forgejo/templates/forgejo.service.j2
diff --git a/ansible/roles/forgejo/templates/nginx-forgejo.conf.j2 b/infrastructure/ansible2/roles/forgejo/templates/nginx-forgejo.conf.j2
similarity index 100%
rename from ansible/roles/forgejo/templates/nginx-forgejo.conf.j2
rename to infrastructure/ansible2/roles/forgejo/templates/nginx-forgejo.conf.j2
diff --git a/ansible/roles/keycloak/handlers/main.yml b/infrastructure/ansible2/roles/keycloak/handlers/main.yml
similarity index 100%
rename from ansible/roles/keycloak/handlers/main.yml
rename to infrastructure/ansible2/roles/keycloak/handlers/main.yml
diff --git a/ansible/roles/keycloak/tasks/database.yml b/infrastructure/ansible2/roles/keycloak/tasks/database.yml
similarity index 100%
rename from ansible/roles/keycloak/tasks/database.yml
rename to infrastructure/ansible2/roles/keycloak/tasks/database.yml
diff --git a/ansible/roles/keycloak/tasks/main.yml b/infrastructure/ansible2/roles/keycloak/tasks/main.yml
similarity index 100%
rename from ansible/roles/keycloak/tasks/main.yml
rename to infrastructure/ansible2/roles/keycloak/tasks/main.yml
diff --git a/ansible/roles/keycloak/templates/keycloak.conf.j2 b/infrastructure/ansible2/roles/keycloak/templates/keycloak.conf.j2
similarity index 100%
rename from ansible/roles/keycloak/templates/keycloak.conf.j2
rename to infrastructure/ansible2/roles/keycloak/templates/keycloak.conf.j2
diff --git a/ansible/roles/keycloak/templates/keycloak.service.j2 b/infrastructure/ansible2/roles/keycloak/templates/keycloak.service.j2
similarity index 100%
rename from ansible/roles/keycloak/templates/keycloak.service.j2
rename to infrastructure/ansible2/roles/keycloak/templates/keycloak.service.j2
diff --git a/ansible/roles/keycloak/templates/nginx-keycloak.conf.j2 b/infrastructure/ansible2/roles/keycloak/templates/nginx-keycloak.conf.j2
similarity index 100%
rename from ansible/roles/keycloak/templates/nginx-keycloak.conf.j2
rename to infrastructure/ansible2/roles/keycloak/templates/nginx-keycloak.conf.j2
diff --git a/ansible/roles/keycloak/templates/realm-config.json.j2 b/infrastructure/ansible2/roles/keycloak/templates/realm-config.json.j2
similarity index 100%
rename from ansible/roles/keycloak/templates/realm-config.json.j2
rename to infrastructure/ansible2/roles/keycloak/templates/realm-config.json.j2
diff --git a/ansible/roles/postgresql/defaults/main.yml b/infrastructure/ansible2/roles/postgresql/defaults/main.yml
similarity index 100%
rename from ansible/roles/postgresql/defaults/main.yml
rename to infrastructure/ansible2/roles/postgresql/defaults/main.yml
diff --git a/ansible/roles/postgresql/handlers/main.yml b/infrastructure/ansible2/roles/postgresql/handlers/main.yml
similarity index 100%
rename from ansible/roles/postgresql/handlers/main.yml
rename to infrastructure/ansible2/roles/postgresql/handlers/main.yml
diff --git a/ansible/roles/postgresql/tasks/main.yml b/infrastructure/ansible2/roles/postgresql/tasks/main.yml
similarity index 100%
rename from ansible/roles/postgresql/tasks/main.yml
rename to infrastructure/ansible2/roles/postgresql/tasks/main.yml
diff --git a/ansible/roles/postgresql/templates/pg_hba.conf.j2 b/infrastructure/ansible2/roles/postgresql/templates/pg_hba.conf.j2
similarity index 100%
rename from ansible/roles/postgresql/templates/pg_hba.conf.j2
rename to infrastructure/ansible2/roles/postgresql/templates/pg_hba.conf.j2
diff --git a/ansible/roles/postgresql/templates/postgresql.conf.j2 b/infrastructure/ansible2/roles/postgresql/templates/postgresql.conf.j2
similarity index 100%
rename from ansible/roles/postgresql/templates/postgresql.conf.j2
rename to infrastructure/ansible2/roles/postgresql/templates/postgresql.conf.j2
diff --git a/ansible/roles/powerdns-authoritative/handlers/main.yml b/infrastructure/ansible2/roles/powerdns-authoritative/handlers/main.yml
similarity index 100%
rename from ansible/roles/powerdns-authoritative/handlers/main.yml
rename to infrastructure/ansible2/roles/powerdns-authoritative/handlers/main.yml
diff --git a/ansible/roles/powerdns-authoritative/tasks/firewall.yml b/infrastructure/ansible2/roles/powerdns-authoritative/tasks/firewall.yml
similarity index 100%
rename from ansible/roles/powerdns-authoritative/tasks/firewall.yml
rename to infrastructure/ansible2/roles/powerdns-authoritative/tasks/firewall.yml
diff --git a/ansible/roles/powerdns-authoritative/tasks/main.yml b/infrastructure/ansible2/roles/powerdns-authoritative/tasks/main.yml
similarity index 100%
rename from ansible/roles/powerdns-authoritative/tasks/main.yml
rename to infrastructure/ansible2/roles/powerdns-authoritative/tasks/main.yml
diff --git a/ansible/roles/powerdns-authoritative/tasks/repo.yml b/infrastructure/ansible2/roles/powerdns-authoritative/tasks/repo.yml
similarity index 100%
rename from ansible/roles/powerdns-authoritative/tasks/repo.yml
rename to infrastructure/ansible2/roles/powerdns-authoritative/tasks/repo.yml
diff --git a/ansible/roles/powerdns-authoritative/tasks/schema.yml b/infrastructure/ansible2/roles/powerdns-authoritative/tasks/schema.yml
similarity index 100%
rename from ansible/roles/powerdns-authoritative/tasks/schema.yml
rename to infrastructure/ansible2/roles/powerdns-authoritative/tasks/schema.yml
diff --git a/ansible/roles/powerdns-authoritative/templates/pdns.conf.j2 b/infrastructure/ansible2/roles/powerdns-authoritative/templates/pdns.conf.j2
similarity index 100%
rename from ansible/roles/powerdns-authoritative/templates/pdns.conf.j2
rename to infrastructure/ansible2/roles/powerdns-authoritative/templates/pdns.conf.j2
diff --git a/ansible/roles/powerdns-authoritative/templates/pdns.local.gpgsql.conf.j2 b/infrastructure/ansible2/roles/powerdns-authoritative/templates/pdns.local.gpgsql.conf.j2
similarity index 100%
rename from ansible/roles/powerdns-authoritative/templates/pdns.local.gpgsql.conf.j2
rename to infrastructure/ansible2/roles/powerdns-authoritative/templates/pdns.local.gpgsql.conf.j2
diff --git a/ansible/vault/production-phase2.yml.example b/infrastructure/ansible2/vault/production-phase2.yml.example
similarity index 100%
rename from ansible/vault/production-phase2.yml.example
rename to infrastructure/ansible2/vault/production-phase2.yml.example
diff --git a/ansible/vault/production.yml.example b/infrastructure/ansible2/vault/production.yml.example
similarity index 100%
rename from ansible/vault/production.yml.example
rename to infrastructure/ansible2/vault/production.yml.example
diff --git a/infrastructure/opentofu b/infrastructure/opentofu
new file mode 160000
index 0000000..079b07a
--- /dev/null
+++ b/infrastructure/opentofu
@@ -0,0 +1 @@
+Subproject commit 079b07a49a8afb325c89e6f40b189fa90c29f416
diff --git a/templates/.gitmessage.txt b/infrastructure/templates/.gitmessage.txt
similarity index 100%
rename from templates/.gitmessage.txt
rename to infrastructure/templates/.gitmessage.txt
diff --git a/migrate-alliance-boreale-v2.sh b/migrate-alliance-boreale-v2.sh
new file mode 100755
index 0000000..164aa38
--- /dev/null
+++ b/migrate-alliance-boreale-v2.sh
@@ -0,0 +1,358 @@
+#!/usr/bin/env bash
+set -Eeuo pipefail
+
+# ============================================================================
+# migrate-alliance-boreale-v2.sh
+#
+# Migration prudente vers une structure canonique du dépôt Alliance Boréale.
+#
+# Principes :
+# - DRY_RUN=1 par défaut
+# - ne supprime rien
+# - n'écrase rien silencieusement
+# - journalise tout
+# - évite les auto-déplacements de dossier
+#
+# Usage :
+# bash migrate-alliance-boreale-v2.sh
+# DRY_RUN=0 bash migrate-alliance-boreale-v2.sh
+# ============================================================================
+
+ROOT="${1:-.}"
+cd "$ROOT"
+
+DRY_RUN="${DRY_RUN:-1}"
+STAMP="$(date +%Y%m%d-%H%M%S)"
+LOG_DIR=".migration"
+LOG_FILE="${LOG_DIR}/migration-v2-${STAMP}.log"
+
+mkdir -p "$LOG_DIR"
+
+log() {
+ echo "[$(date +%H:%M:%S)] $*" | tee -a "$LOG_FILE"
+}
+
+run() {
+ if [[ "$DRY_RUN" == "1" ]]; then
+ log "DRY-RUN: $*"
+ else
+ log "RUN: $*"
+ eval "$@" | tee -a "$LOG_FILE"
+ fi
+}
+
+exists() {
+ [[ -e "$1" ]]
+}
+
+ensure_dir() {
+ local d="$1"
+ [[ -d "$d" ]] || run "mkdir -p \"$d\""
+}
+
+safe_mv() {
+ local src="$1"
+ local dst="$2"
+
+ if [[ ! -e "$src" ]]; then
+ log "SKIP: source absente: $src"
+ return 0
+ fi
+
+ if [[ "$src" == "$dst" ]]; then
+ log "SKIP: source et destination identiques: $src"
+ return 0
+ fi
+
+ ensure_dir "$(dirname "$dst")"
+
+ if [[ -e "$dst" ]]; then
+ local backup="${dst}.pre-migration-${STAMP}"
+ log "CONFLIT: destination existe: $dst"
+ run "mv \"$dst\" \"$backup\""
+ fi
+
+ run "mv \"$src\" \"$dst\""
+}
+
+safe_mkdir_tree() {
+ for d in "$@"; do
+ ensure_dir "$d"
+ done
+}
+
+move_if_exists() {
+ local src="$1"
+ local dst="$2"
+ exists "$src" && safe_mv "$src" "$dst" || log "SKIP: absent: $src"
+}
+
+quarantine_if_exists() {
+ local src="$1"
+ local bucket="$2"
+ if exists "$src"; then
+ ensure_dir "$bucket"
+ safe_mv "$src" "$bucket/$(basename "$src")"
+ fi
+}
+
+create_readme_if_absent() {
+ local path="$1"
+ local content="$2"
+
+ if [[ ! -e "$path" ]]; then
+ ensure_dir "$(dirname "$path")"
+ if [[ "$DRY_RUN" == "1" ]]; then
+ log "DRY-RUN: création de $path"
+ else
+ printf "%s\n" "$content" > "$path"
+ log "RUN: création de $path"
+ fi
+ fi
+}
+
+log "Début migration v2"
+log "ROOT=$ROOT"
+log "DRY_RUN=$DRY_RUN"
+
+# ----------------------------------------------------------------------------
+# 1) Créer uniquement les branches structurelles sûres
+# ----------------------------------------------------------------------------
+
+log "Création de l’ossature cible"
+
+safe_mkdir_tree \
+ docs \
+ infrastructure \
+ operations \
+ archives \
+ tooling \
+ security \
+ docs/decisions \
+ docs/diffusion \
+ archives/pre-migration \
+ archives/legacy-docs \
+ archives/obsolete
+
+# Répertoires feuilles qui ne reçoivent pas un mv de dossier entier existant
+safe_mkdir_tree \
+ docs/decisions/adr \
+ docs/rfc \
+ docs/diffusion/conferences \
+ docs/diffusion/site \
+ docs/diffusion/visuels \
+ docs/diffusion/recrutement \
+ operations/runbooks \
+ operations/evidence \
+ operations/procedures \
+ operations/checklists \
+ infrastructure/opentofu \
+ infrastructure/cloud-init \
+ infrastructure/netbox \
+ infrastructure/templates/proxmox
+
+# ----------------------------------------------------------------------------
+# 2) Déplacer les blocs racine évidents
+# ----------------------------------------------------------------------------
+
+log "Déplacement des blocs racine évidents"
+
+move_if_exists "ansible" "infrastructure/ansible"
+move_if_exists "templates" "infrastructure/templates"
+move_if_exists "evidence" "operations/evidence"
+move_if_exists "configure" "tooling/configure"
+
+# ----------------------------------------------------------------------------
+# 3) Réorganiser docs/ par familles
+# ----------------------------------------------------------------------------
+
+if exists "docs"; then
+ log "Réorganisation de docs/"
+
+ # Dossiers historiques -> familles cibles
+ move_if_exists "docs/00-fondements" "docs/fondements"
+ move_if_exists "docs/10-architecture" "docs/architecture"
+ move_if_exists "docs/40-ecosystemes" "docs/ecosystemes"
+ move_if_exists "docs/constitution" "docs/gouvernance"
+ move_if_exists "docs/20-rag" "docs/corpus-a-integrer"
+ move_if_exists "docs/vieustoq" "archives/legacy-docs/vieustoq"
+
+ # engineering / guides / opération
+ move_if_exists "docs/engineering" "docs/guides-engineering"
+ move_if_exists "docs/guides" "docs/guides"
+ move_if_exists "docs/opération" "operations/procedures"
+
+ # pile opérateur -> recentrage
+ move_if_exists "docs/pile opérateur/adr" "docs/decisions/adr"
+ move_if_exists "docs/pile opérateur/pol" "docs/politiques"
+ move_if_exists "docs/pile opérateur/runbooks" "operations/runbooks"
+ move_if_exists "docs/pile opérateur/evidence" "operations/evidence/pile-operateur"
+ move_if_exists "docs/pile opérateur/configs" "operations/procedures/pile-operateur-configs"
+
+ # Ce qui reste du dossier "pile opérateur" part en quarantaine s'il existe encore
+ quarantine_if_exists "docs/pile opérateur/README.md" "archives/pre-migration/docs-pile-operateur"
+ quarantine_if_exists "docs/pile opérateur" "archives/pre-migration"
+
+ # annexes -> corpus à intégrer
+ move_if_exists "docs/50-annexes" "docs/corpus-a-integrer-annexes"
+
+ # assets / diffusion
+ move_if_exists "docs/assets" "docs/diffusion/visuels/assets"
+
+ # fichiers de diffusion
+ move_if_exists "docs/Alliance_Boreale_Conferences.pptx" "docs/diffusion/conferences/Alliance_Boreale_Conferences.pptx"
+ move_if_exists "docs/Conference_01_Rideau_ou_Coffre_Fort.pptx" "docs/diffusion/conferences/Conference_01_Rideau_ou_Coffre_Fort.pptx"
+ move_if_exists "docs/Conference_02_Colonisation_Numerique.pptx" "docs/diffusion/conferences/Conference_02_Colonisation_Numerique.pptx"
+ move_if_exists "docs/2026-02-03 - Présentation d'Alliance Boréale - Rencontres Linux.odp" "docs/diffusion/conferences/2026-02-03-Rencontres-Linux.odp"
+ move_if_exists "docs/alliance_boreale_site.html" "docs/diffusion/site/alliance_boreale_site.html"
+ move_if_exists "docs/alliance_boreale_recrutement.docx" "docs/diffusion/recrutement/alliance_boreale_recrutement.docx"
+
+ # fichiers racine documentaires à classer proprement
+ move_if_exists "docs/00_Etat_Depot_Vivant_v1.md" "docs/gouvernance/00_Etat_Depot_Vivant_v1.md"
+ move_if_exists "docs/00_Glossaire_biomimetique_autopoietique_v3.md" "docs/modele-glossaire.md"
+ move_if_exists "docs/00_Modele_8_couches_biomimetique_autopoietique_v3.md" "docs/modele-8-couches.md"
+ move_if_exists "docs/00_Nomenclature_v4.md" "docs/nomenclature-v4.md"
+ move_if_exists "docs/06 - Controles_Conformite_Label_Prestige_par_Couche_v1.0.md" "docs/politiques/06-Controles_Conformite_Label_Prestige_par_Couche_v1.0.md"
+
+ # divers à trier plus tard
+ for f in \
+ "docs/index.md" \
+ "docs/linkedin_post.md" \
+ "docs/TODO.md" \
+ "docs/TRANSMISSION.md"
+ do
+ if exists "$f"; then
+ move_if_exists "$f" "docs/corpus-a-integrer/$(basename "$f")"
+ fi
+ done
+fi
+
+# ----------------------------------------------------------------------------
+# 4) Corriger certaines branches créées implicitement
+# ----------------------------------------------------------------------------
+
+log "Consolidation des branches documentaires"
+
+# Si gouvernance n'existe pas encore après déplacement depuis constitution
+ensure_dir "docs/gouvernance"
+ensure_dir "docs/corpus-a-integrer"
+ensure_dir "docs/politiques"
+
+# Si les fichiers modèle ont été déplacés en racine docs, on leur donne une maison
+ensure_dir "docs/modele"
+move_if_exists "docs/modele-glossaire.md" "docs/modele/00_Glossaire_biomimetique_autopoietique_v3.md"
+move_if_exists "docs/modele-8-couches.md" "docs/modele/00_Modele_8_couches_biomimetique_autopoietique_v3.md"
+move_if_exists "docs/nomenclature-v4.md" "docs/modele/00_Nomenclature_v4.md"
+
+# Si on a guides-engineering, le ranger sous guides
+if exists "docs/guides-engineering"; then
+ ensure_dir "docs/guides"
+ move_if_exists "docs/guides-engineering" "docs/guides/engineering"
+fi
+
+# Si corpus-a-integrer-annexes existe, le ranger sous corpus-a-integrer
+if exists "docs/corpus-a-integrer-annexes"; then
+ ensure_dir "docs/corpus-a-integrer"
+ move_if_exists "docs/corpus-a-integrer-annexes" "docs/corpus-a-integrer/annexes"
+fi
+
+# ----------------------------------------------------------------------------
+# 5) Doubles probables -> quarantaine prudente
+# ----------------------------------------------------------------------------
+
+log "Mise en quarantaine des doublons probables"
+
+ensure_dir "archives/pre-migration/duplicates"
+
+for f in \
+ "docs/fondements/00-manifeste.md" \
+ "docs/fondements/00 - Manifeste.md" \
+ "docs/corpus-a-integrer/03_Cadre_Conformite_Label_Prestige(1).md" \
+ "docs/corpus-a-integrer/devis(2).md"
+do
+ if exists "$f"; then
+ move_if_exists "$f" "archives/pre-migration/duplicates/$(basename "$f")"
+ fi
+done
+
+# ----------------------------------------------------------------------------
+# 6) README d’orientation
+# ----------------------------------------------------------------------------
+
+create_readme_if_absent "docs/README.md" \
+"# Documentation canonique
+
+Ce dossier contient la documentation de référence de l'Alliance Boréale.
+
+Branches principales :
+- fondements
+- modele
+- architecture
+- gouvernance
+- decisions
+- politiques
+- ecosystemes
+- guides
+- corpus-a-integrer
+- diffusion
+"
+
+create_readme_if_absent "infrastructure/README.md" \
+"# Infrastructure
+
+Contient l'implémentation opératoire :
+- ansible
+- opentofu
+- cloud-init
+- templates
+- netbox
+"
+
+create_readme_if_absent "operations/README.md" \
+"# Operations
+
+Contient :
+- runbooks
+- evidence
+- procedures
+- checklists
+"
+
+create_readme_if_absent "archives/README.md" \
+"# Archives
+
+Contient :
+- legacy
+- variantes remplacées
+- artefacts déplacés pendant migration
+"
+
+# ----------------------------------------------------------------------------
+# 7) Rapport final
+# ----------------------------------------------------------------------------
+
+log "Migration v2 terminée"
+log "Journal: $LOG_FILE"
+
+cat <