vCenter et hôtes ESXi¶
Rôle¶
vcenter.infra.indio (VMware vCenter Server 8.0.3) est le plan de contrôle central de toute la
plateforme de virtualisation Indio. Il gouverne le cluster à 2 hôtes ESXi qui porte le datastore
vSAN (voir vsan.md), l'ensemble des groupes de ports du DVS (dont les segments overlay
NSX, voir nsx.md), et sert de cible de placement à toute VM déployée par le
module Terraform /root/vmware (indio/iac/vmware) ainsi qu'au template doré produit par
/root/packer (voir packer-template.md).
Point important, déjà établi et reconfirmé dans cette page : vCenter/ESXi et la formation du
cluster vSAN lui-même (2 nœuds + witness) sont hors Terraform — construits et administrés à la
main via l'UI vCenter/govc. Le dépôt /root/vmware ne fait que consommer ces objets déjà
existants (data sources) pour y cloner des VM.
Architecture¶
vCenter¶
| Élément | Valeur |
|---|---|
| FQDN | vcenter.infra.indio |
| Produit | VMware vCenter Server 8.0.3, build 25413364 |
| Compte admin | administrator@infra.indio (domaine SSO = infra.indio, pas le défaut vsphere.local) |
| Datacenter | Datacenter |
| Cluster de calcul | Cluster |
Les 2 hôtes ESXi + le witness¶
Cluster vSAN à 2 nœuds, topologie standard VMware (2 hôtes de données + 1 appliance witness tierce pour le quorum) :
| Hôte | IP | Rôle | CPU | RAM | Version |
|---|---|---|---|---|---|
esxi-node01.infra.indio |
10.15.100.11 | Nœud de données 1 | Dell, Xeon Gold 6144 @3.50GHz, 16 CPU logiques | 785 029 MB | VMware ESXi 8.0.3, build 25429389 |
esxi-node02.infra.indio |
10.15.100.12 | Nœud de données 2 | Dell, Xeon Gold 6144 @3.50GHz, 16 CPU logiques | 458 113 MB | VMware ESXi 8.0.3, build 25429389 |
witness.infra.indio |
— | Appliance witness (quorum vSAN) | — | — | Objet /Datacenter/host/witness.infra.indio, hors du conteneur Cluster |
Vérifié en direct (2026-07-19)
govc host.info esxi-node01.infra.indio esxi-node02.infra.indio confirme les deux hôtes
connected, même build ESXi, même heure de boot (2026-07-18 09:30:4x — redémarrage
coordonné récent, cohérent avec une fenêtre de maintenance/patch commune). L'écart de RAM
entre les deux hôtes (785 Go vs 458 Go) est réel et observé tel quel — voir Points d'attention.
Le witness n'est pas un nœud de calcul : il ne porte aucune VM applicative, il stocke uniquement les composants "witness" (métadonnées de quorum) des objets vSAN, ce qui permet à un cluster à seulement 2 nœuds de données de survivre à la perte d'un des deux sans split-brain.
Réseau : le DVS DSwitch et ses groupes de ports¶
Le cluster est raccordé à un unique Distributed Virtual Switch (DSwitch), avec :
- des groupes de ports d'infrastructure vSphere :
DPortGroup-MGMT,DPortGroup-vSAN,DPortGroup-vMotion,DPortGroup-Front,DPortGroup-workload,DSwitch-DVUplinks-28; - les segments overlay NSX attachés au même DVS (un groupe de ports par segment créé côté NSX
Manager, consommé ici comme cible de
network_interfacepar les VM) :seg-admin,seg-service,seg-data,seg-supervision,seg-identite,seg-soc,seg-soc-admin,seg-proxy,seg-proxy-dns,seg-storage,seg-sauvegarde,seg-t0-uplink,seg-edge-uplinks— détail complet (CIDR, DHCP, rôle) dans nsx.md.
dvportgroup-2002 = seg-storage (vérifié par govc find/object.collect) : c'est ce groupe de
ports que consomme le vSAN File Service (voir vsan-file-service.md).
Dossiers VM (rangement par segment)¶
Convention posée le 2026-07-05 (voir la note "renommage" dans les autres pages) : chaque projet
Terraform place ses VM dans un dossier vCenter nommé d'après le segment réseau NSX cible, pas
le rôle applicatif — vsphere_folder = "seg-xxx" (valeur relative, le provider vsphere préfixe
lui-même /Datacenter/vm/).
Constaté en direct (govc ls /Datacenter/vm) : dossiers seg-supervision, seg-proxy-dns,
seg-data, seg-service, seg-identite, seg-soc, seg-proxy présents, plus Templates,
Admin, ESX Agents (VM système, voir vsan-file-service.md) et veeam
(VM Veeam existantes, hors IaC). D'autres objets à la racine (nutanix, haproxy-v0.2.0, nsx,
vCLS, VMware vCenter Server, Discovered virtual machine) ne relèvent pas de ce module et sont
hors périmètre de cette page.
Comptes de service vCenter¶
Quatre comptes de service AD dédiés à l'automatisation, tous assignés au même rôle custom
svc-vm-automation au niveau /Datacenter (propagate = Yes) :
| Compte | Consommateur |
|---|---|
svc-packer@infra.indio |
/root/packer (build du template) |
svc-terraform@infra.indio |
Modules Terraform (dont /root/vmware) |
svc-veeam@infra.indio |
Sauvegarde Veeam (hors IaC) |
svc-horizon@infra.indio |
Horizon (hors IaC) |
Vérifié en direct (2026-07-19)
govc permissions.ls /Datacenter confirme les 4 comptes liés au rôle svc-vm-automation
avec propagate=Yes. govc role.ls svc-vm-automation confirme la présence du privilège
VirtualMachine.Interact.PutUsbScanCodes (voir Points d'attention) au milieu d'un ensemble
classique de privilèges VirtualMachine.*/Datastore.*/Resource.*/Network.Assign — un
rôle taillé pour cloner, configurer et piloter des VM, rien de plus large (pas de droit sur
les hôtes, le cluster ou le réseau physique).
Schéma — topologie du cluster¶
flowchart TD
subgraph VC["vCenter Server 8.0.3 (vcenter.infra.indio)"]
DC["Datacenter"]
end
DC --> CL["Cluster (vSAN 2 nœuds)"]
DC --> WIT["witness.infra.indio<br/>(hors conteneur Cluster)"]
CL --> N1["esxi-node01.infra.indio<br/>10.15.100.11 · 785 Go RAM"]
CL --> N2["esxi-node02.infra.indio<br/>10.15.100.12 · 458 Go RAM"]
N1 & N2 --> DVS["DVS DSwitch"]
DVS --> PG1["DPortGroup-MGMT / vSAN / vMotion / Front / workload"]
DVS --> PG2["Segments overlay NSX<br/>(seg-admin, seg-service, seg-storage, ...)"]
N1 & N2 -.contribuent des disques.-> VSAN[("vsanDatastore")]
WIT -.quorum uniquement, pas de données.-> VSAN
style WIT stroke-dasharray: 5 5
Schéma — du template au clonage (module /root/vmware)¶
sequenceDiagram
participant TF as Terraform (/root/vmware)
participant VC as vCenter
participant VM as VM clonée
TF->>VC: data sources (datacenter, cluster,<br/>datastore, network, template)
TF->>VC: vsphere_virtual_machine.vm (clone du template)
VC->>VM: clone + customize (hostname, IP statique, DNS)
VM-->>VM: 1er boot (config réseau appliquée)
TF->>VM: provisioner file (add_disk_lvm.sh + mdp sudo temporaire)
TF->>VM: provisioner remote-exec (user applicatif, LVM, cleanup)
Note over VM: Baseline OS déjà présente (RPM indio-baseline-config,<br/>voir baseline-config.md) — héritée du template, pas de ce module
Structure du dépôt /root/vmware¶
vmware/
├── versions.tf # provider vsphere >= 2.6.0, terraform >= 1.5.0
├── variables.tf # connexion vCenter, placement, définition VM, réseau, disque, SSH
├── main.tf # data sources + resource vsphere_virtual_machine
├── outputs.tf # vm_name, vm_ip, vm_uuid, data_disk, app_user
├── terraform.tfvars.example # à copier en terraform.tfvars (secrets réels, jamais commité)
└── scripts/
└── add_disk_lvm.sh # PV/VG/LV + montage fstab durci, exécuté par un provisioner
Le dépôt déclare une seule VM par état (pas de for_each/map sur une liste de nœuds) : c'est
un module générique, destiné à être dupliqué ou paramétré par projet consommateur plutôt qu'à
décrire toute la flotte dans un seul état.
Provisioning Terraform¶
main.tf s'articule en deux parties :
- Data sources :
vsphere_datacenter,vsphere_compute_cluster,vsphere_datastore,vsphere_network,vsphere_virtual_machine(le templatetmpl-rocky96-hardened). Aucune de ces ressources n'est créée par ce module — uniquement lue. C'est le mécanisme technique qui matérialise la règle "ce module ne provisionne pas le cluster" : toute tentative de déployer sans que ces objets existent déjà échoue auplan. - Resource
vsphere_virtual_machine.vm: - Clone du template (
clone.template_uuid) ; CPU/RAM/firmware/scsi_typedéfinis par variable, disque système hérité du template (taille, thin provisioning, eager scrub copiés depuis les données du template via la data source). - Disque de données optionnel (
dynamic "disk", piloté parvar.add_data_disk,unit_number = 1). clone.customize: hostname, domaine, IP statique, masque, passerelle et serveurs DNS pour la VM — customization VMware Tools au clonage, c'est ce bloc qui pose une IP différente de l'IP figée du template au build (voir packer-template.md).lifecycle.ignore_changessurannotation,clone[0].template_uuidetdisk[0].io_share_count— évite un diff/redéploiement accidentel si le template doré change de version (nouveau build Packer) ou si l'annotation vSphere est modifiée manuellement.
Variables principales (variables.tf) : connexion vCenter (vsphere_server/user/password
marquée sensitive, vsphere_insecure), placement (vsphere_datacenter/cluster/datastore/
network/folder), caractéristiques VM (vm_cpu défaut 2, vm_ram défaut 4096 Mo), réseau
(vm_ip, vm_netmask, vm_gateway, vm_dns), utilisateur applicatif (app_user,
app_user_pubkey, app_user_sudo), disque de données (add_data_disk, data_disk_size_gb défaut
50, data_lvm_vg/data_lvm_lv/data_mount_point/data_fs_type), et accès SSH pour les
provisioners (ssh_username défaut indio-adm, ssh_password marquée sensitive).
outputs.tf expose vm_name, vm_ip, vm_uuid, un résumé du disque de données (data_disk) et
app_user.
Configuration Ansible¶
Ce dépôt n'utilise pas Ansible. Le provisioning post-clonage est fait directement par des provisioners Terraform natifs, exécutés en SSH juste après la customization :
provisioner "file"(×2) : déposescripts/add_disk_lvm.shsur la VM, puis le mot de passe sudo dans un fichier temporaire/tmp/.tf_sudo_pass(permissions 600) plutôt qu'en argument de commande — il n'apparaît donc ni dans les logs Terraform/CI ni dans la table des processus (ps) de la VM.provisioner "remote-exec":chmod 600sur le fichier de mot de passe, création idempotente de l'utilisateur applicatif (id ... || useradd), ajout au groupewheelsiapp_user_sudo, dépôt de la clé publique SSH siapp_user_pubkeyest fournie, exécution deadd_disk_lvm.shsiadd_data_disk, puis suppression des fichiers temporaires.
scripts/add_disk_lvm.sh : rescanne les hôtes SCSI, détecte le premier disque sans partition ni PV
LVM existant, crée PV/VG/LV, formate (XFS par défaut), monte sur le point demandé avec des options
durcies (nodev,nosuid), et ajoute une entrée /etc/fstab idempotente basée sur l'UUID du volume.
Idempotent : si aucun disque libre n'est trouvé mais que le LV attendu existe déjà, il vérifie
seulement le montage.
La configuration OS plus large de la flotte (comptes, proxy, DNS, dépôts internes, NTP) est prise
en charge en amont par le template Packer et en aval par /root/baseline (Ansible) — voir
baseline-config.md. Ce module ne s'occupe que du strict nécessaire au
placement/réseau/disque de données.
Procédure manuelle¶
Le cluster vSAN (hôtes + witness) et le rangement vCenter sont construits/maintenus hors Terraform. Aucun log détaillé pas-à-pas de la construction initiale du cluster n'a été conservé ; les procédures ci-dessous sont soit des runbooks déjà exécutés et vérifiés (2, 3, 4), soit la méthode standard VMware reproductible pour reconstruire l'élément concerné (1) — cohérente avec la topologie réellement observée dans cette page.
1. Formation du cluster vSAN à 2 nœuds + witness (procédure standard VMware, à suivre en cas de reconstruction complète — pas un journal vérifié de l'exécution initiale) :
- Créer le cluster dans le Datacenter, y ajouter
esxi-node01/esxi-node02. - Activer vSAN sur le cluster en topologie 2 nœuds (pas stretched, pas de fault domain custom).
- Déployer l'appliance witness (OVA VMware fourni) sur un site/hyperviseur tiers, la configurer avec son propre réseau de management, puis la désigner comme witness du cluster depuis l'assistant vSAN.
- Réclamer les disques de chaque hôte en groupes de disques (cache tier + capacity tier).
- Vérifier
vSAN Health(Skyline) avant de considérer le cluster prêt à recevoir des VM.
2. Rattachement d'un hôte au DVS après un incident de préparation NSX (exécuté et vérifié le 2026-07-11, cf. nsx.md pour le contexte transport node) :
govc host.maintenance.enter -host.ip=<ip-esxi> # laisser tourner sans annuler, peut prendre plusieurs minutes
# ... nettoyage/reconfiguration DVS interne à vSphere ...
govc dvs.add -dvs=DSwitch -pnic=vmnic1,vmnic2,vmnic3 esxi-node02.infra.indio
govc host.maintenance.exit -host.ip=<ip-esxi>
Effet de bord vérifié, pas une hypothèse
Mettre un hôte portant des VM agents système (vSAN File Service, nsx-manager, vCenter lui-même) en mode maintenance peut déclencher un nettoyage EAM qui désactive des services cluster entiers en plus d'évacuer les VM concernées. C'est exactement ce qui est arrivé au vSAN File Service ce jour-là — postmortem complet dans vsan-file-service.md. Avant toute mise en maintenance d'un hôte de ce cluster, vérifier quelles VM agents/système y tournent.
3. Rangement des VM par dossier vCenter (segment NSX) :
govc folder.create /Datacenter/vm/seg-xxx
govc object.mv /Datacenter/vm/NOM-VM /Datacenter/vm/seg-xxx
Puis déclarer vsphere_folder = "seg-xxx" (valeur relative) côté Terraform pour que les futurs
clones y atterrissent directement.
4. Comptes de service et rôle svc-vm-automation : la création initiale des 4 comptes AD et du
rôle custom n'est pas détaillée dans un log conservé (probablement faite via l'UI vCenter — Menu
Administration > Rôles, puis Utilisateurs et groupes AD > attribution de permission sur
/Datacenter). Le correctif suivant, lui, est vérifié et directement reproductible :
Nécessaire pour que le boot_command de Packer (voir
packer-template.md) fonctionne — sans ce privilège précis (distinct de
ConsoleInteract), l'injection de touches clavier via l'API échoue avec Permission to perform
this operation was denied. Le rôle étant partagé par les 4 comptes, le correctif bénéficie aux
quatre simultanément.
5. Bascule du template canonique : après un nouveau build Packer réussi (nom temporaire type
tmpl-rocky96-hardened-v3), renommage manuel pour que tmpl-rocky96-hardened (le nom attendu par
var.template_name de tous les projets Terraform consommateurs) pointe sur le nouveau build :
govc object.rename /Datacenter/vm/tmpl-rocky96-hardened tmpl-rocky96-hardened-old
govc object.rename /Datacenter/vm/tmpl-rocky96-hardened-v3 tmpl-rocky96-hardened
Grâce à lifecycle.ignore_changes sur clone[0].template_uuid (voir plus haut), cette bascule ne
provoque aucun diff sur les VM déjà déployées — seuls les futurs clones héritent du nouveau
template.
Procédure de déploiement¶
cp terraform.tfvars.example terraform.tfvars # éditer les valeurs réelles (jamais commité)
terraform init
terraform plan
terraform apply
Le mot de passe SSH utilisé par les provisioners est celui du compte indio-adm déjà en place sur
le template (hérité du build Packer, éventuellement changé depuis par une rotation fleet-wide) ; il
ne doit être renseigné qu'en local dans terraform.tfvars, jamais versionné.
Pour un usage en équipe, le README recommande un backend d'état distant (ex. state Terraform géré par GitLab) plutôt que le state local actuellement utilisé — non implémenté dans ce dépôt à ce jour.
Contrôle de santé / Vérification¶
Commandes read-only utilisées pour vérifier cette page (2026-07-19), réutilisables comme runbook :
export GOVC_URL=https://vcenter.infra.indio GOVC_USERNAME=administrator@infra.indio \
GOVC_PASSWORD='...' GOVC_INSECURE=1
govc about # version/build vCenter
govc ls /Datacenter/host/Cluster # hôtes + réseaux du cluster
govc host.info esxi-node01.infra.indio esxi-node02.infra.indio # état connected/build
govc permissions.ls /Datacenter # comptes de service + rôles assignés
govc role.ls svc-vm-automation # privilèges du rôle partagé
Résultat au moment de la vérification : les deux hôtes connected, même build ESXi
(25429389), rôle svc-vm-automation bien assigné aux 4 comptes de service avec
PutUsbScanCodes présent.
Points d'attention¶
- Ce module ne crée pas le cluster vSAN. Le Datacenter, le Cluster (2 nœuds ESXi + witness) et
vsanDatastoresont gérés hors Terraform, au niveau vSphere/ESXi. Le dépôt se contente de les référencer par data source pour y déployer des VM. - Asymétrie de RAM entre les deux hôtes (785 Go sur
esxi-node01contre 458 Go suresxi-node02, observée en direct) : à vérifier si volontaire (contrainte matérielle/budget) ou à corriger — une asymétrie de capacité entre nœuds d'un cluster vSAN à 2 nœuds peut limiter la capacité de bascule complète d'un hôte vers l'autre en cas de panne. - Le template
tmpl-rocky96-hardenedest observé directement à la racine de/Datacenter/vm, pas dans le dossierTemplates(qui existe mais n'est pas utilisé en pratique malgrévsphere_folderpar défaut de Packer valant"Templates") — écart mineur, sans impact fonctionnel. terraform.tfvarsetterraform.tfstate*sont gitignorés (identifiants vCenter réels + état) : ne jamais les committer ni les recopier dans une documentation.ssh_passwordetvsphere_passwordsont marquéessensitive = truecôté Terraform mais restent transmises en clair aux provisioners (authentification SSH par mot de passe) — choix cohérent avec l'activation dePasswordAuthentication yessur le template doré (voir packer-template.md), à ne pas reproduire tel quel si une politique clé-uniquement est adoptée plus tard.lifecycle.ignore_changessurclone[0].template_uuid: un changement de version du template doré n'entraîne pas de diff sur les VM déjà déployées — seuls les futurs clones héritent du nouveau template.- Pas de backend d'état distant configuré : un usage multi-opérateur nécessiterait de migrer le state hors du disque local.
- Le rôle
svc-vm-automationest partagé par 4 comptes (svc-packer/svc-veeam/svc-horizon/svc-terraform) : tout ajustement de privilège (ex. le correctifPutUsbScanCodes) impacte simultanément les quatre usages, à garder en tête avant toute modification. - Toute mise en maintenance d'un des deux hôtes doit être précédée d'un inventaire des VM agents/système qui y tournent (nsx-manager, vCenter, vSAN File Service) — voir l'encadré danger ci-dessus et le postmortem détaillé dans vsan-file-service.md.