Aller au contenu

Jetons API et comptes de service (Terraform, Ansible, supervision)

Day 1 · DéployerNiveau 3 · MaîtriserProcédureRédigé · à valider en lab

Objectif : donner à chaque outil (Terraform, Ansible, Zabbix, Prometheus) sa propre identité technique, avec un jeton API limité au strict nécessaire, révocable et daté, au lieu de réutiliser root@pam et son mot de passe.

Principe

Élément Exemple Rôle
Compte de service svc-terraform@pve Porte les droits maximums de l'outil. Pas de mot de passe utilisé.
Jeton svc-terraform@pve!ci Identité utilisée par l'outil. Format USER@REALM!TOKENID.
Secret UUID affiché une seule fois À ranger immédiatement au coffre (Vault, coffre de la CI).
Privilege separation --privsep 1 (défaut) Le jeton n'a que les ACL posées sur lui, dans la limite de celles de l'utilisateur.
Expiration --expire <epoch> Le jeton est refusé après la date. 0 = jamais.

En-tête HTTP utilisé par les outils :

Authorization: PVEAPIToken=svc-terraform@pve!ci=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx

Avec --privsep 0, le jeton hérite de tous les droits de l'utilisateur : plus simple, mais on ne peut plus restreindre un jeton par rapport à un autre. Recommandation MSP : privsep 1 et ACL explicites sur le jeton.

Droits types par outil

Outil Chemin Rôle conseillé
Supervision (Zabbix « Proxmox VE by HTTP », prometheus-pve-exporter) / PVEAuditor (lecture seule)
Ansible (cycle de vie des VM d'un pool) /pool/ansible, /storage/ceph-vm PVEVMAdmin, PVEDatastoreUser
Terraform (clonage de templates, cloud-init) /pool/terraform, stockages, VNet ou bridge Rôle personnalisé TerraformProv (ci-dessous)
Script de sauvegarde ponctuelle /vms/101, /storage/pbs-local PVEVMUser, PVEDatastoreUser

Avant de toucher la prod

  • Besoin exprimé par outil : quelles VM, quels stockages, lecture ou écriture.
  • Pool dédié créé (terraform, ansible) pour cantonner les VM gérées par l'outil.
  • Coffre de secrets prêt à recevoir le secret (il ne sera plus jamais affiché).
  • Date d'expiration choisie et rappel de rotation planifié.
  • Les privilèges listés existent bien sur la version installée (pveum role list) : VM.Monitor n'existe plus en PVE 9.

Étapes

1. Créer le compte de service et son rôle

  1. Datacenter → Permissions → Roles → Create TerraformProv, cocher les privilèges listés dans l'onglet CLI.
  2. Datacenter → Permissions → Users → Add : svc-terraform, realm Proxmox VE authentication server, sans mot de passe utile, commentaire « Compte de service Terraform – propriétaire : équipe infra ».
  3. Permissions → Add → User Permission : chemin /pool/terraform, utilisateur svc-terraform@pve, rôle TerraformProv. Idem sur /storage/ceph-vm et /sdn/zones/localnetwork si l'outil doit brancher les VM sur un bridge local.
pveum role add TerraformProv --privs "VM.Allocate VM.Clone VM.Audit \
  VM.Config.CDROM VM.Config.CPU VM.Config.Cloudinit VM.Config.Disk \
  VM.Config.HWType VM.Config.Memory VM.Config.Network VM.Config.Options \
  VM.PowerMgmt VM.Console VM.Migrate VM.GuestAgent.Audit \
  Datastore.AllocateSpace Datastore.Audit SDN.Use Sys.Audit Pool.Audit"
pveum user add svc-terraform@pve --comment "Compte de service Terraform"
pveum pool add terraform
pveum acl modify /pool/terraform --user svc-terraform@pve --role TerraformProv
pveum acl modify /storage/ceph-vm --user svc-terraform@pve --role TerraformProv
pveum acl modify /sdn/zones/localnetwork --user svc-terraform@pve --role PVESDNUser

2. Créer le jeton

Datacenter → Permissions → API Tokens → Add : utilisateur svc-terraform@pve, Token ID ci, Privilege Separation coché, Expire renseigné. Copier le secret affiché dans le coffre avant de fermer la fenêtre.

pveum user token add svc-terraform@pve ci --privsep 1 \
  --expire $(date -d 2027-06-30 +%s) --comment "CI GitLab" --output-format json

3. Donner des droits au jeton (privsep 1)

Permissions → Add → API Token Permission : mêmes chemins et rôles que pour l'utilisateur, jeton svc-terraform@pve!ci.

pveum acl modify /pool/terraform --token 'svc-terraform@pve!ci' --role TerraformProv
pveum acl modify /storage/ceph-vm --token 'svc-terraform@pve!ci' --role TerraformProv
pveum acl modify /sdn/zones/localnetwork --token 'svc-terraform@pve!ci' --role PVESDNUser

Les guillemets simples empêchent le shell d'interpréter le !.

4. Cas de la supervision

pveum user add svc-monitoring@pve --comment "Supervision Zabbix"
pveum user token add svc-monitoring@pve zabbix --privsep 1
pveum acl modify / --user svc-monitoring@pve --role PVEAuditor
pveum acl modify / --token 'svc-monitoring@pve!zabbix' --role PVEAuditor

Sur PBS, l'équivalent est proxmox-backup-manager user generate-token <user> <jeton> avec l'en-tête PBSAPIToken=, et un rôle Audit pour la supervision.

Vérifications

pveum user token permissions svc-terraform@pve ci
# liste /pool/terraform, /storage/ceph-vm ... avec les privilèges attendus
curl -s -H 'Authorization: PVEAPIToken=svc-terraform@pve!ci=<secret>' \
  'https://pve01.corp.local:8006/api2/json/cluster/resources?type=vm' | jq '.data | length'
# nombre de VM visibles : uniquement celles du pool terraform

Un appel hors périmètre (par exemple DELETE sur une VM hors pool) doit répondre 403 Permission check failed.

Rollback

Révoquer un jeton est immédiat et sans effet sur les autres : pveum user token remove svc-terraform@pve ci (GUI : API Tokens → Remove). Rotation : créer ci2, basculer l'outil, supprimer ci.

Pièges vus en support

  • Jeton créé avec privsep 1 mais ACL posées seulement sur l'utilisateur : le jeton ne voit rien, l'outil renvoie des listes vides ou des 403.
  • Jeton de root@pam avec privsep 0 dans un dépôt Git : compromission complète du cluster. Révoquer et auditer.
  • Terraform crée la VM mais échoue à lire son IP : privilège VM.GuestAgent.Audit manquant (PVE 9).
  • Rôle personnalisé importé d'un ancien script avec VM.Monitor : la création échoue en PVE 9.
  • Template à cloner hors du pool terraform : erreur 403 au clonage. Placer le template dans le pool ou donner VM.Clone et VM.Audit sur /vms/<id-template>.
  • Secret perdu : il ne peut pas être relu, seulement recréé.
  • Certaines opérations exigent root@pam en session (pas en jeton), par exemple certains paramètres matériels avancés ou l'upload de snippets par certains outils qui passent alors par SSH.

Quand ouvrir un ticket iTop

Suspicion de fuite d'un jeton : P2 sécurité, révoquer d'abord, puis ticket pour analyse des journaux. Conception d'un modèle de comptes de service pour une chaîne CI/CD : P4. Ne jamais envoyer un secret dans le ticket.

Ouvrir un ticket iTop

Pour aller plus loin