Fullmoon System

Déployer The Operations Loop : de PXE à NetBox, AWX et Zabbix

AI_Manager

Cet article détaille la procédure réelle d’installation de serveurs, d’actifs, d’automatisation et de supervision interconnectés sur quatre réseaux internes de VirtualBox. Les services centraux sont co-implantés sur fml-ops-01/02, mais les unités de gestion sont séparées via Compose et K3s. Les procédures pour les environnements en ligne et isolés sont indiquées pour chaque étape.

Les commandes se basent sur les adresses et les versions fixes de cet exercice. Les mots de passe, jetons et clés privées SSH ne sont pas inclus dans les exemples ou sur Git. Les espaces réservés dans les fichiers de configuration doivent être injectés depuis votre propre coffre de secrets. La portée exécutée et les résultats réels doivent être vérifiés sur la base de l’article de validation.

Séquence de cet article

1. Versions et ordre d’installation

Composant Version et méthode utilisées Raison du choix
Virtualisation / OS VirtualBox 7.2.18 / Rocky Linux 10.2 Pratique Linux reproductible sur un PC réel
Docker / Compose 29.8.1 / 5.5.1 Gestion des conteneurs pour le serveur central et le proxy
Zabbix 7.0.30 LTS Server/Web/Proxy/Agent 2 Correspondance des versions entre le serveur et le proxy, correctifs LTS officiels fixes
NetBox 4.7.1, netbox-docker 5.1.1 Gestion des actifs basée sur l’API avec deux applications/Workers
PostgreSQL / Patroni PostgreSQL 15 / Patroni 4.1.5 Réplication de la base de données centrale et basculement des rôles
Redis / etcd Redis 7.4 / etcd 3.7.1 Détermination des pannes distribuées avec Sentinel
AWX / Operator 24.6.1 / 2.19.1 Méthode d’installation par opérateur officiel
K3s v1.37.0+k3s1 Base d’exécution AWX pour machine virtuelle unique
Collection NetBox netbox.netbox 3.23.0 Plugin d’inventaire utilisant le jeton Bearer NetBox v2

L’ordre d’installation est le suivant : OS / réseau → DNS/NTP / CA → etcd / PostgreSQL / Redis → VIP d’accès → NetBox / Zabbix → Proxy / Bastion par environnement → K3s / AWX / Git → Cibles PXE → Intégration de l’automatisation → Vérification des pannes / de la restauration. Même si l’interface utilisateur des étapes ultérieures s’affiche, vérifiez d’abord si le rôle de base de données, la résolution de noms et la synchronisation horaire des étapes précédentes sont corrects.

Le terme « récent » correspond à la version fixe basée sur la configuration du 2026-09-20. Lors des reconstructions ultérieures, vérifiez à nouveau les politiques de support et les condensés d’images, et ne mélangez pas les versions de cet article avec de nouvelles versions. Distinguez la dernière version générale de Zabbix et la dernière version LTS officielle.

2. Préparation des machines virtuelles et du réseau

CORE est 10.77.10.0/24, PROD est 10.77.20.0/24, DEV est 10.77.30.0/24 et STG est 10.77.40.0/24. Créez-les respectivement en tant que réseaux internes fml-core/prod/dev/stg. Attachez les quatre cartes réseau de réseau interne à Gateway et Provision, et connectez Edge et les cibles à leur propre réseau d’environnement.

Lors de la configuration sur un réseau en ligne

Vérifiez la somme de contrôle de l’ISO officiel et créez un modèle d’installation minimale de Rocky. Pour la machine virtuelle de gestion, séparez et utilisez la carte réseau NAT et la carte réseau interne pendant la période d’installation. La redirection de port SSH de l’hôte doit être liée uniquement à 127.0.0.1. Ne connectez pas le NAT à la machine virtuelle PXE cible.

$VBox = 'C:\Program Files\Oracle\VirtualBox\VBoxManage.exe'
& $VBox list vms
& $VBox showvminfo fml-ops-01 --machinereadable
# Créer la cible uniquement sur un disque vide approuvé.
.\lab-v2\Create-PxeTarget.ps1 -Environment prod

Lors de la clonation de modèles, créez de nouveaux hostname, machine-id, clé d’hôte SSH et adresse MAC. Assurez-vous que l’adresse fixe, la clé et le machine-id du modèle d’origine ne restent pas sur plusieurs machines virtuelles. Maintenez SELinux Enforcing et firewalld, et restreignez la connexion à distance et par mot de passe root.

Lors de la configuration sur un réseau fermé

Importez l’ISO, les packages d’installation vérifiés, l’autorité de certification interne, les clés publiques et les modèles de configuration, puis créez la même structure de réseau interne. Même sans connecter de carte réseau NAT, vous devez pouvoir accéder à l’installation du système d’exploitation et au DNS/NTP interne. Enregistrez « l’installation existante avec le NAT désactivé ultérieurement » et « l’installation dès le début en important les dépendances nécessaires » comme des tests distincts.

Sur ce PC, le démarrage à 2 vCPU d’une nouvelle cible BIOS PXE s’est arrêté, j’ai donc utilisé 1 vCPU. La machine centrale numéro 1 a été exécutée avec 4 vCPU sur le profil CPU Intel Core i7-6700K. Ce nom de profil n’est pas le processeur réel du PC. Hyper-V/VBS/l’intégrité de la mémoire n’ont pas été modifiés. Les problèmes de machines virtuelles détaillés sont traités dans un blog séparé.

3. Routage, DNS, NTP et chemins d’accès

La communication inter-environnements est autorisée par la politique firewalld de la Gateway. Provision est directement connecté à chaque environnement pour fournir DHCP, PXE et le stockage, et n’est pas utilisé comme routeur.

Origine Destination Port Objet
Central .11/.12 Environnement Edge .10 TCP 22 Accès Bastion
Environnement Edge .10 Cible approuvée .101 TCP 22 Transfert SSH
Cible d’environnement Même environnement Edge .10 TCP 10051 Données Agent Active
Environnement Edge .10 Central .11/.12 TCP 10051 Proxy Active et Serveur HA
Réseau d’environnement approuvé VIP 10.77.10.10 TCP 443 API/Web NetBox/Zabbix/AWX
Cible d’environnement Même environnement Provision .20 DNS 53, NTP 123, HTTP 80, ports liés à PXE Installation, résolution de noms, heure, stockage interne
Central/quorum Nœud de service interne correspondant etcd 2379/2380, Patroni 8008, PG 5432/6432, Redis 6379/26379, NFS 2049 Réplication de données, arbitrage, support partagé

Le tableau ci-dessus résume les objectifs de communication. Pour les règles d’autorisation réelles, vérifiez conjointement le pare-feu hôte et la politique du routeur. Ne exposez pas DB, etcd et Redis à Internet ou à l’ensemble des réseaux d’environnement.

En cas de configuration sur le réseau en ligne

Installez les paquets nécessaires sur la machine virtuelle d’administration, puis créez l’interface interne et la route statique. Ne mélangez pas la route par défaut pour Internet et la route statique du réseau de TP.

nmcli connection modify fml-internal \
  +ipv4.routes '10.77.20.0/24 10.77.10.1'
nmcli connection modify fml-internal \
  +ipv4.routes '10.77.30.0/24 10.77.10.1'
nmcli connection modify fml-internal \
  +ipv4.routes '10.77.40.0/24 10.77.10.1'
nmcli device reapply enp0s8
ip route
chronyc tracking

En cas de configuration sur un réseau isolé

Dans le DNS interne, résolvez netbox.fullmoon.test, zabbix.fullmoon.test et awx.fullmoon.test vers le VIP 10.77.10.10, et git.fullmoon.test vers 10.77.10.12. Ne dépendez pas d’un repli (fallback) sur un DNS externe. Utilisez le chrony de Provision comme référence interne, mais prévoyez une source horaire et une politique de synchronisation validées séparément pour la production réelle.

getent hosts netbox.fullmoon.test git.fullmoon.test
chronyc sources -v
ip route get 10.77.20.10

L’accès par navigateur se fait via les noms HTTPS depuis un terminal d’administration qui fait confiance à l’AC de TP. Si le réseau interne n’est pas routé directement depuis Windows, un tunnel SSH de bouclage (loopback) peut être utilisé. Vérifiez d’abord qu’aucun port local 443 n’est déjà utilisé.

ssh -i <관리용_개인키> -p 22031 -N -L 127.0.0.1:443:10.77.10.10:443 labadmin@127.0.0.1

Dans le fichier hosts du terminal d’administration, associez les trois noms de services à 127.0.0.1 et enregistrez les certificats d’AC publique vérifiés dans le magasin de confiance. Ne récupérez pas la clé privée de l’AC du serveur. Pour y accéder même pendant un test de panne du nœud central 1, utilisez le port SSH d’administration 22032 du nœud central 2. Ignorer les avertissements de certificat ne doit pas être considéré comme une procédure de connexion normale.

4. Runtime de conteneur et lot d’importation

En cas de configuration sur un réseau en ligne

Installez Docker/Compose à partir du dépôt RHEL officiel de Docker. Les chemins des projets Compose sont divisés en /opt/fullmoon-lab/core, /opt/fullmoon-lab/apps et /opt/fullmoon-lab/edge. Les fichiers d’environnement sensibles doivent appartenir à root avec des permissions 0600, et les répertoires parents avec 0700.

docker version
docker compose version
docker compose --project-directory /opt/fullmoon-lab/core \
  -f /opt/fullmoon-lab/core/compose.yml config --quiet
docker image inspect --format '{{json .RepoDigests}}' \
  zabbix/zabbix-server-pgsql:alpine-7.0.30

Étant donné que la sortie complète du fichier compose rendu peut contenir des mots de passe, ne stockez pas le contenu de config dans des journaux publics. Distinguez également si SELinux est en mode Enforcing sur l’hôte et si l’intégration SELinux du démon Docker est activée. Ce TP maintient le mode Enforcing sur l’hôte mais ne prétend pas être un environnement où l’intégration SELinux de Docker est également appliquée.

En cas de configuration sur un réseau isolé

Téléchargez les RPM et leurs dépendances depuis une machine virtuelle de préparation connectée partageant la même architecture CPU et la même version majeure de Rocky. L’archive d’images Docker et l’archive K3s/containerd sont distinctes. Le fait d’avoir chargé des images dans Docker ne signifie pas qu’elles peuvent être utilisées dans K3s.

# VM de préparation : enregistrer les versions requises des RPM et toutes leurs dépendances
dnf download --resolve --alldeps --destdir ./rpms \
  docker-ce docker-ce-cli containerd.io docker-compose-plugin
createrepo_c ./rpms
docker image save -o images.tar <반입할_고정_이미지_목록>
sha256sum images.tar > images.tar.sha256

# Après le transfert vers le réseau isolé
sha256sum -c images.tar.sha256
docker image load -i images.tar
k3s ctr images import fullmoon-ee-r2.tar

La liste d’importation comprend : l’ISO de l’OS et le dépôt RPM, Docker/Compose, le résultat de la compilation de Patroni, les images NetBox/Zabbix/Redis/etcd, les binaires K3s et les images airgap, les images Operator/proxy RBAC/AWX/EE, le bundle Git, les modèles de configuration et l’AC publique, ainsi que les clés de signature et les sommes de contrôle. Vérifiez sur une nouvelle cible dépourvue de carte réseau externe afin d’éviter toute réussite accidentelle grâce au cache de la machine virtuelle de préparation.

5. Configuration de PostgreSQL, etcd et Redis

etcd et Sentinel sont déployés sur les deux nœuds centraux et le nœud de quorum. PostgreSQL/Patroni et Redis sont déployés sur les deux nœuds centraux. La base de données sépare les comptes et les bases de données pour NetBox, Zabbix et AWX.

En cas de configuration sur un réseau en ligne

Extrayez/compilez les images fixes et placez les variables NODE_NAME/NODE_IP par nœud, la configuration de Patroni, la configuration de Redis/Sentinel et les fichiers de secrets restreints. Vérifiez que les trois nœuds etcd communiquent entre eux avant de démarrer la base de données centrale.

docker compose --project-directory /opt/fullmoon-lab/core \
  -f /opt/fullmoon-lab/core/compose.yml --profile central up -d
docker compose --project-directory /opt/fullmoon-lab/core \
  -f /opt/fullmoon-lab/core/compose.yml exec -T postgres \
  patronictl -c /etc/patroni/patroni.yml list
curl --fail http://10.77.10.11:8008/patroni
curl --fail http://10.77.10.12:8008/patroni

Le nœud de quorum exécute uniquement etcd et Sentinel sans le profil central. Le mode synchronous_mode de Patroni a été activé et synchronous_mode_strict a été défini sur false. L’état de réplication et le risque de perte de validation en cas de panne doivent être évalués en fonction des conditions opérationnelles. La méthode consistant à faire de chaque base de données un maître manuel n’est pas utilisée.

En cas de configuration sur un réseau isolé

Étant donné que le Dockerfile de Patroni nécessite des dépôts externes tels que pip et apt, complétez les images lors de la phase de préparation en ligne avant de les importer. Évitez de compiler à la volée sur site en rencontrant des dépendances Internet. Chargez la même archive sur les deux nœuds centraux, comparez les ID d’image, puis démarrez selon la même procédure.

Le port de connexion DB d’HAProxy est le 6432. Seuls les nœuds dont le /primary de Patroni renvoie 200 sont utilisés comme backend d’écriture de la base de données. Avec le délai d’attente (timeout) initial de 60 secondes, les connexions inactives à la base de données risquant d’être interrompues, les délais client/serveur de l’écouteur de la base de données ont été dissociés à 1 heure. Ajustez cette valeur en fonction des requêtes réelles et de la politique de pool de connexions.

6. VIP, HTTPS et redondance de NetBox

Le VIP de Keepalived est 10.77.10.10, et le nœud prioritaire par défaut est ops01. L’HAProxy des deux nœuds se connecte à NetBox sur le port 8082, Zabbix Web sur le port 8080 et AWX sur le port 30080. Les rôles actifs de Node, DB, Redis et VIP ne doivent pas nécessairement se trouver toujours sur le même nœud.

En cas de configuration sur un réseau en ligne

Émettez un certificat incluant les trois noms web dans le SAN à l’aide de l’AC de TP, et placez le certificat et la clé sur les deux nœuds centraux avec des permissions restreintes. NetBox App et Worker utilisent la même SECRET_KEY, le même jeton pepper d’API et la même configuration Redis Sentinel.

# Principales relations de configuration dans netbox-configuration.py
DATABASES = {'default': {
    'ENGINE': 'django.db.backends.postgresql',
    'NAME': 'netbox', 'USER': 'netbox',
    'PASSWORD': '<비밀_파일에서_주입>',
    'HOST': '127.0.0.1', 'PORT': 6432,
}}
# Utiliser les mêmes valeurs SECRET_KEY / API_TOKEN_PEPPERS sur les deux nœuds App.
# Pour REDIS tasks/caching, préciser le service Sentinel et les numéros de DB respectifs.

Le format réel de chaque version du fichier de configuration par défaut est utilisé en se basant sur la configuration NetBox fournie et la documentation officielle. Si vous ne faites que correspondre les noms de variables d’environnement sans les lire depuis la configuration Python, elles ne seront pas appliquées. La migration initiale de la base de données est d’abord achevée sur un nœud, puis le reste des nœuds et le Worker sont démarrés.

Le stockage multimédia est partagé depuis le répertoire /srv/fullmoon/netbox-media du quorum via NFSv4. Seuls les deux nœuds centraux sont autorisés à l’exportation et root_squash est maintenu. Vérifiez l’UID réel de l’image NetBox pour adapter les permissions du répertoire. Le booléen SELinux NFS vérifié dans cet environnement Rocky est virt_use_nfs.

findmnt /srv/fullmoon/netbox-media
haproxy -c -f /etc/haproxy/haproxy.cfg
keepalived -t -f /etc/keepalived/keepalived.conf
systemctl is-active haproxy keepalived
curl --fail https://netbox.fullmoon.test/login/ -o /dev/null

En cas de configuration sur un réseau isolé

L’image NetBox contient les dépendances Python nécessaires à son exécution, importez donc l’image avec le même condensé (digest) sur les deux nœuds. Intégrez l’AC interne non seulement sur l’hôte, mais aussi dans AWX EE. Préparez également une procédure de récupération des secrets afin que la SECRET_KEY et le pepper ne diffèrent pas entre les deux nœuds. L’interruption de NFS ayant un impact sur les médias indépendamment du succès de l’API web, testez-la séparément.

Le problème rencontré en pratique a été la vérification de santé (health check) de NetBox. Lors de la vérification de /login/ sans l’en-tête HTTP/1.1 Host, NetBox renvoyait une erreur 400, ce qui poussait HAProxy à considérer tous les backends comme hors service (down) et le VIP renvoyait alors une erreur 503. L’en-tête Host a été spécifié comme suit.

backend netbox_ui
    mode http
    option httpchk
    http-check send meth GET uri /login/ ver HTTP/1.1 hdr Host netbox.fullmoon.test
    http-check expect status 200
    server ops01 10.77.10.11:8082 check
    server ops02 10.77.10.12:8082 check

Lors des tests de panne, les nouvelles tentatives par défaut de la connexion Redis ont entraîné un délai d’environ 55,6 secondes pour une seule consultation du cache NetBox. Nous avons vérifié NetBox 4.7.1 et le code de django-redis, puis avons modifié le comportement pour interroger d’abord le Sentinel local. Le cache a spécifié les délais de connexion et de réponse ainsi que la politique de nouvelle tentative dans les KWARGS pris en charge. Le bouclage (loopback) représente une autre adresse de connexion pour le même Sentinel et ne constitue pas l’ajout d’un membre supplémentaire au quorum.

from redis.backoff import NoBackoff
from redis.retry import Retry

# Interroger d’abord le Sentinel local de chaque nœud NetBox.
SENTINELS = [('127.0.0.1', 26379), ('10.77.10.13', 26379),
             ('10.77.10.11', 26379), ('10.77.10.12', 26379)]
REDIS['caching']['KWARGS'] = {
    'socket_connect_timeout': 3,
    'socket_timeout': 3,
    'retry': Retry(NoBackoff(), 0),
}

Étant donné qu’il s’agit d’une valeur restreinte pour renvoyer rapidement les erreurs, les nouvelles tentatives pour chaque requête et le temps de récupération du service sont deux choses différentes. Le temps nécessaire à la récupération de l’API après une panne du nœud principal de la base de données ou de Redis est indiqué dans l’article de vérification. Ne généralisez pas en supposant que les mêmes résultats s’appliqueront sous la charge de production ou avec d’autres versions.

7. Zabbix LTS HA et Proxy/Bastion par environnement

En cas de configuration sur un réseau en ligne

Server/Web/Proxy utilisent le tag alpine-7.0.30 et Agent 2 pour la cible Rocky utilise le RPM 7.0.30 pour el10. Les deux serveurs pointent vers une base de données Zabbix commune mais sont configurés avec des valeurs HANodeName et NodeAddress différentes. Web a été configuré pour ne pas fixer l’adresse d’un serveur spécifique, mais pour trouver le nœud actif à partir des informations HA.

# ops01
ZBX_HANODENAME=fml-ops-01
ZBX_NODEADDRESS=10.77.10.11:10051
# ops02
ZBX_HANODENAME=fml-ops-02
ZBX_NODEADDRESS=10.77.10.12:10051
# Séparer par un point-virgule les adresses du même cluster HA pour le proxy actif
ZBX_SERVER_HOST=10.77.10.11:10051;10.77.10.12:10051

Le nom du proxy doit correspondre exactement au nom enregistré dans l’API Zabbix. Distinguez le PSK du proxy et le PSK de l’agent selon l’environnement. Placez les données SQLite du proxy sur un volume persistant et appliquez une politique de tampon disque (disk buffer). On ne peut considérer le fonctionnement du tampon comme vérifié qu’après avoir confirmé que les données en attente ont été retransmises suite à une coupure.

Lors d’une configuration dans un réseau fermé

Les images Proxy sont importées via docker load. L’Agent RPM est fourni via le dépôt interne tout en conservant la vérification de la signature GPG. Cet RPM el10 a été vérifié avec la clé B5333005. La configuration utilisant uniquement l’ancienne clé A14FE591 ayant échoué lors de la vérification, l’empreinte (fingerprint) de la clé de signature officielle a été vérifiée et ajoutée.

rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-ZABBIX-B5333005
rpm -K zabbix-agent2-7.0.30-release1.el10.x86_64.rpm
# Empreinte vérifiée de la clé
# 4C3D6F2CC75F5146754FC374D913219AB5333005

Le Bastion effectue uniquement un transfert (forwarding) vers la cible de l’environnement .101:22. Le shell interactif et le transfert d’agent (agent forwarding) ne sont pas autorisés. La connexion jusqu’à la cible s’établit à partir de la clé centrale et aucune clé privée n’est placée sur l’Edge. Tout en préservant l’accès SSH du compte d’administration existant, une vérification est effectuée avec sshd -t avant d’exécuter un reload.

Match User bastion
    AuthenticationMethods publickey
    AllowTcpForwarding local
    PermitOpen 10.77.20.101:22
    PermitTTY no
    AllowAgentForwarding no
    ForceCommand /bin/false
Match all

8. Git, K3s, AWX et environnement d’exécution

Lors d’une configuration dans un réseau en ligne

Le dépôt Git nu (bare repository) est /srv/git/fullmoon-automation.git sur ops02. AWX récupère la branche main grâce à la clé de déploiement en lecture seule de fmlgit. Le chemin de la commande forcée (forced command) a été entouré de guillemets simples afin que git-shell puisse l’interpréter.

restrict,command="git-upload-pack '/srv/git/fullmoon-automation.git'" ssh-ed25519 <공개키>

K3s a été installé sur ops01 et SELinux ainsi que le chiffrement des Secret ont été activés. Traefik, ServiceLB et metrics-server ont été exclus car ils ne sont pas nécessaires pour ce TP. AWX est figé sur l’Operator 2.19.1 et AWX 24.6.1, et le Secret PostgreSQL pointe vers le chemin 6432 de la HA DB existante. Le mot de passe administrateur, le mot de passe de la base de données et le bundle CA sont injectés sous forme de Secret Kubernetes.

k3s kubectl -n awx get pods,jobs
k3s kubectl -n awx apply -f awx.yml
curl --fail https://awx.fullmoon.test/api/v2/ping/

Étant donné que le chemin gcr.io initial de l’image du proxy RBAC de l’Operator renvoyait une erreur 404, il a été corrigé par l’image officielle quay.io/brancz de la même version v0.15.0. Dans le CRD AWX, le paramètre cookie doit être une chaîne de caractères et host_aliases un tableau. Si SYSTEM_TASK_ABS_MEM est saisi sous forme de nombre, le code AWX associé appelle des méthodes de chaînes de caractères et le répartiteur (dispatcher) échoue ; les configurations manuelles superflues ont donc été supprimées.

Lors d’une configuration dans un réseau fermé

Importez toutes les images airgap de K3s ainsi que l’ensemble des images générées par l’Operator. En particulier, si les images init, migration, EE ou du proxy RBAC sont absentes, l’installation ne s’effectuera pas, même si l’image Web est présente. Après l’importation dans containerd de K3s, vérifiez que le nom réel de l’image correspond au nom du CR.

L’EE (Execution Environment) du TP est awx-ee:24.6.1, auquel ont été ajoutés netbox.netbox:3.23.0, une CA publique, ainsi que la clé d’hôte Git/Edge SSH vérifiée. Le nom de l’image est localhost/fullmoon-ee:24.6.1-netbox3.23.0-r2 et la politique de récupération (pull policy) de l’environnement d’exécution AWX est Never. La présence de localhost dans le nom ne signifie pas qu’un registre a été exécuté ; ce sont les images locales préalablement importées dans K3s qui sont utilisées.

k3s ctr images import fullmoon-ee-r2.tar
k3s ctr images list
git bundle verify fullmoon-automation.bundle

Dans AWX, créez un Projet, un inventaire bootstrap d’approbation, une source d’inventaire NetBox, un identifiant (credential) SSH, des identifiants API NetBox/Zabbix, un Modèle de tâche (Job Template) d’intégration/vérification (Onboard/Verify) ainsi qu’un Workflow. Le chemin de réussite du Workflow est Onboard → Synchronisation de l’inventaire NetBox → Verify. AWX lui-même est configuré de manière unique sur la 1ère machine centrale. Ne déduisez pas une haute disponibilité (HA) avec répartition physique sur la seule base du champ ha du ping de l’API.

9. Installation d’un serveur vide par PXE et Kickstart

Lors d’une configuration dans un réseau en ligne

Vérifiez l’ISO Rocky Minimal officielle et mettez l’arborescence d’installation à disposition dans /var/www/html/rocky sur Provision. L’ISO réelle contient Minimal/repodata. L’utilisation directe des chemins BaseOS/AppStream du DVD génère une erreur 404. Le DHCP associe uniquement les adresses MAC approuvées de chaque environnement à l’adresse .101.

fml-prod-app-01 : 08:00:27:a0:20:65 → 10.77.20.101
fml-dev-app-01  : 08:00:27:a0:30:65 → 10.77.30.101
fml-stg-app-01  : 08:00:27:a0:40:65 → 10.77.40.101

Sur VirtualBox pour ce PC, la combinaison BIOS + ipxe-legacy.iso officiel a permis de faire fonctionner l’ensemble du processus : DHCP → noyau/initrd HTTP → Kickstart. Le fichier iPXE est le support de démarrage qui initie l’installation réseau et les paquets du système d’exploitation sont récupérés depuis Provision. Créez la nouvelle machine virtuelle avec un disque vide de 32 Gio, 4 Gio de RAM pour l’installation, et 1 vCPU, puis réduisez la RAM à 1 Gio après l’installation.

La section %pre de Kickstart n’autorise le partitionnement qu’après avoir vérifié l’adresse MAC, l’identification VirtualBox du DMI, la présence de /dev/sda et l’absence de signature sur le disque. Le mot de passe root est verrouillé et les éléments suivants sont configurés : la clé publique labadmin, sshd, sudo, chrony et firewalld. La clé d’hôte SSH laissée par %post est enregistrée après avoir été comparée avec l’historique de la console de la VM de confiance. N’acceptez jamais aveuglément une clé d’hôte inconnue.

Lors d’une configuration dans un réseau fermé

Importez le même ISO, les mêmes fichiers de démarrage et le même Kickstart dans le serveur HTTP interne. La cible ne possède pas de carte réseau externe et reçoit le DNS, le NTP et les paquets depuis la machine Provision du même environnement. En configurant également un dépôt interne pour l’Agent 2, il est possible d’effectuer la configuration de base même en l’absence de dépôt RPM externe.

Lors de l’application à un serveur physique, ne supprimez pas simplement la protection DMI de VirtualBox pour l’exécuter. Après avoir mappé séparément le numéro de série réel approuvé, le BMC, l’adresse MAC, les disques logiques RAID, le WWN de la cible d’installation, l’UEFI/Secure Boot et les pilotes de cartes réseau, vous devez évaluer la portée de la destruction des disques. La preuve d’installation réelle dans cet article provient d’une machine virtuelle et ne doit pas être présentée comme le résultat de la validation sur un matériel serveur physique.

10. Connexion de l’API d’actifs, de l’inventaire et de la supervision

Lors d’une configuration dans un réseau en ligne

Le compte d’écriture des actifs de NetBox se voit attribuer les autorisations nécessaires sur les VM, les périphériques (Device), les interfaces, les adresses IP et les catalogues, tandis que le compte d’inventaire ne dispose que de droits de lecture. La création initiale des champs personnalisés (Custom Field) et des catalogues est effectuée via un bootstrap séparé. Le jeton v2 de NetBox 4.7 est au format Bearer nbt_. Le compte d’automatisation Zabbix restreint les groupes gérés ainsi que les méthodes API et attribue une date d’expiration au jeton.

plugin: netbox.netbox.nb_inventory
api_endpoint: https://netbox.fullmoon.test
token:
  type: Bearer
  value: "{{ lookup('env', 'NETBOX_TOKEN') }}"
validate_certs: true
query_filters:
  - tag: auto
  - status: active

Pour l’étape de collecte, déployez le collecteur Python dans un répertoire temporaire arbitraire et supprimez-le systématiquement après son exécution. Comparez le nom d’hôte réel, l’identifiant de machine (machine ID) et la carte réseau/IP d’administration de la cible avec l’inventaire approuvé. Si les valeurs diffèrent ou si l’adresse IP existante est attribuée à un autre actif, interrompez le processus avant toute modification dans NetBox. N’incluez pas le jeton d’API ou l’ensemble de l’environnement /proc dans les résultats de la collecte.

Les tâches API s’exécutent dans l’EE AWX avec delegate_to: localhost. Si la variable ansible_become destinée à la cible est propagée aux tâches locales, l’EE risque de rechercher sudo et d’échouer ; spécifiez donc les éléments suivants :

delegate_to: localhost
become: false
vars:
  ansible_become: false
  ansible_python_interpreter: "{{ ansible_playbook_python }}"

L’ordre d’enregistrement est le suivant : actifs réels / Interface / IPAM → hôte / Proxy / modèle Zabbix → synchronisation de la source d’inventaire NetBox → validation de la ligne de base (baseline) de la cible et des données Zabbix les plus récentes. Les API NetBox et Zabbix ne constituant pas une transaction de base de données unique, la réexécution est prise en charge en cas de succès partiel, et aucune action corrective (compensation) ne supprime aveuglément les actifs ayant déjà été enregistrés avec succès.

Lors d’une configuration dans un réseau fermé

Le code API n’utilisant que du HTTPS interne, la méthode reste identique. La CA de l’EE, les collections, les bibliothèques Python, la clé d’hôte SSH épinglée (pinned) et le commit Git doivent tous avoir été importés. Aucun paquet n’est téléchargé depuis Galaxy ou pip pendant l’exécution des tâches. Spécifiez uniquement les dépôts fullmoon-minimal et fullmoon-zabbix sur la cible pour installer l’Agent.

ServerActive=10.77.20.10:10051
Hostname=fml-prod-app-01
TLSConnect=psk
TLSAccept=psk
TLSPSKIdentity=fml-prod-app-01
TLSPSKFile=/etc/zabbix/agent.psk

Le fichier PSK doit appartenir à l’utilisateur zabbix avec des permissions réglées sur 0400, et sa valeur ne doit pas être consignée dans les journaux d’AWX. Vérifiez l’absence de doublons parmi les hôtes gérés ainsi que lastclock/lastvalue pour l’élément le plus récent. Ne considérez pas l’opération comme terminée sur la seule base de la réponse de création d’hôte.

Fin de l’installation et liaison automatique du Workflow

Le composant fullmoon-postinstall.timer de la 1ère machine centrale confirme la fin de l’installation de la cible approuvée. SSH transite par le Bastion correspondant et vérifie la clé d’hôte enregistrée. Si /var/lib/fullmoon-lab/pxe-installed, le nom d’hôte et l’identifiant de machine (machine ID) correspondent, le Workflow s’exécute en enchaînant : Synchronisation du projet → Synchronisation de l’inventaire bootstrap → Ciblage d’une seule machine via le paramètre limit. L’ID de la tâche et son état sont consignés dans le fichier state.json accessible uniquement par root.

La clé d’hôte SSH créée initialement est recoupée avec la console série VirtualBox de confiance pour être ajoutée à la liste des éléments approuvés. Le contrôleur reste en attente tant que cette identité n’a pas été validée. N’acceptez pas automatiquement une clé inconnue. Par la suite, la détection de la fin de l’installation, l’enregistrement dans l’API et la vérification de la supervision s’enchaînent automatiquement. Sur un serveur physique, cet enregistrement d’identité doit être relié à la console du BMC ou à la procédure d’émission de certificats SSH CA de l’organisation.

systemctl status fullmoon-postinstall.timer
journalctl -u fullmoon-postinstall.service --since '-30min'
# Réussite : launched → AWX workflow ID → completed
# Échec : manual_review_required. Ne pas relancer automatiquement l’enregistrement avant d’en avoir vérifié la cause.

Ce contrôleur et AWX résidant sur ops01, toute défaillance de ce nœud interrompt les nouveaux intégrations (onboarding). Si ops02 (qui héberge Git) est interrompu, la synchronisation des nouveaux projets échoue. Si le fichier d’état est perdu ou si le processus s’arrête immédiatement après la réponse d’exécution, le même Workflow risque d’être relancé ; c’est pourquoi l’enregistrement des actifs a lui aussi été conçu de manière à pouvoir être réexécuté en vérifiant les doublons d’identifiants et d’adresses IP.

11. Informations de connexion et guide d’exploitation simplifié

Fonctionnalité Chemin d’accès Vérification du fonctionnement
NetBox https://netbox.fullmoon.test État VM/Device, Interface, IP primaire, état de collecte
Zabbix https://zabbix.fullmoon.test État HA, dernier accès du Proxy, données les plus récentes de l’hôte
AWX https://awx.fullmoon.test Révision du projet, mise à jour de l’inventaire, résultats Workflow/Job
Git ssh://fmlgit@git.fullmoon.test/srv/git/fullmoon-automation.git Synchronisation SCM en lecture seule
SSH d’administration loopback 22031~22038 Authentification par clé publique labadmin de la VM concernée
SSH cible Via le Bastion selon l’environnement Clé d’hôte approuvée et restriction .101:22

Les contrôles quotidiens s’effectuent dans l’ordre suivant : synchronisation horaire · disque/mémoire → rôle BD/Redis → App/Worker → HA/VIP → Proxy → données réelles de l’Agent → derniers échecs AWX. Ne vous limitez pas à vérifier si le conteneur est Up.

df -h
free -m
chronyc tracking
docker ps --format '{{.Names}} {{.Status}}'
k3s kubectl -n awx get pods
systemctl is-active haproxy keepalived

Lors de l’ajout d’un nouveau serveur, enregistrez d’abord l’inventaire approuvé, MAC/IP, Bastion PermitOpen et la clé d’hôte SSH, puis validez (commit) dans Git. Après la synchronisation du projet, spécifiez uniquement cet hôte avec limit. Vérifiez l’IP primaire et le groupe d’environnement dans NetBox avant de le passer en production. Ne remplacez pas l’ensemble des serveurs en cours d’exécution par une cible illimitée all.

La modification des mots de passe et le renouvellement des tokens doivent être gérés conjointement avec le coffre de secrets, les identifiants AWX et la portée du redémarrage des services. Les tokens expirés, les clés d’hôte SSH modifiées et les ID de machine différents ne sont pas contournés automatiquement. Après une panne de nœud, restaurez le réplica sur la base du primaire survivant et n’activez pas arbitrairement l’écriture sur un nœud isolé.

12. Clôture par la sauvegarde, la mise à jour et la validation

Gérez séparément la sauvegarde logique PostgreSQL, les médias NetBox, le dépôt Git, la SECRET_KEY et la base de données d’AWX, ainsi que les autorités de certification (CA), la configuration et les données secrétes. Les snapshots de VM ne remplacent pas une sauvegarde cohérente au niveau des applications. L’existence d’un fichier de sauvegarde et sa restauration dans une base de données isolée pour lire les mêmes actifs constituent deux vérifications distinctes.

Les mises à jour doivent enregistrer conjointement le tag/digest de l’image ainsi qu’EE/collection, et être effectuées après validation. La migration de NetBox ou la mise à niveau majeure de la base de données pouvant ne pas être réversibles par un simple retour à l’image précédente, préparez des procédures de sauvegarde et de restauration des données. Dans un réseau fermé (air-gapped), créez de nouveaux lots d’importation de mise à jour et de checksum tout en conservant le lot de validation précédent.

La décision de fin de déploiement comprend : l’enregistrement des actifs, la synchronisation des inventaires, les valeurs de supervision les plus récentes, la réexécution, le refus de conflit d’adresses, le basculement en cas de panne de service, la récupération du tampon du Proxy, la restauration de la sauvegarde et l’installation de cibles sans communication externe. Les tests réellement exécutés et les éléments non exécutés sont consignés séparément dans le projet de vérification.

Lectures associées et documentation de configuration

Article original du portfolio · Guide de construction des réseaux en ligne et fermés · Scénarios de panne et historique de validation · Historique de résolution des problèmes de configuration VirtualBox

ZIP des sources d’automatisation et de configuration du labo · ZIP SHA-256

Le ZIP public contient les modèles de configuration et les sources d’automatisation. Il n’inclut pas les images OS, RPM, conteneur ni les informations d’identification. Configurez-le avec vos propres adresses, CA publiques, clés SSH autorisées et coffre de secrets avant de l’appliquer.