0051 — Options natives Ansible (idempotence, check_mode, server-side apply, handlers)
Contexte
Section intitulée « Contexte »Une fois une brique en Ansible
(ADR 0049), encore faut-il
exploiter les directives natives plutôt que de réimplémenter en
command/shell. L’idempotence est déjà largement couverte (77 when:, 37
changed_when:, 26 retries:), mais des écarts subsistent (issue #265),
vérifiés : check_mode absent partout (0 occurrence) ; des
changed_when: true constants (postfix) qui rapportent « changed » à tort et
pilotent un handler de restart ; server_side_apply à 5 endroits seulement
; un traitement de CRDs hétérogène (module vs kubectl shell).
Cet ADR fixe comment écrire les tâches d’un rôle, en s’appuyant sur le patron de rôle posé par l’ADR 0049 (il ne le redéfinit pas).
Décision
Section intitulée « Décision »- (a)
changed_whenreflète le vrai changement — jamaistrueconstant sur une commande idempotente. Unpostconf -en’émet rien quand la valeur est inchangée → dériverchanged_whendu résultat réel (comparer viapostconf -henregistré, ou regex sur stdout). Unchanged_whenqui pilote un handler de service (restart postfix) est un changement de comportement → banc-requis, prouvé par le scénario 22 (Mailpit). - (b)
check_mode: falsesur toutcommand/shelldont le stdout enregistré pilote une logique aval, pour rester compatible--check(dry-run). Ajout purement additif de l’attribut (sans toucherchanged_when/when) → vérifiable statiquement. Cibles :containerd config default(k8s-CRI-install),kubeadm token create(k8s-pre-join),nerdctl manifest inspect(platform-build-images), comptage disques (ceph-pre-install),swapon --show(k8s-pre-install). - (c)
server_side_apply(via le modulekubernetes.core.k8s, avecfield_managerdédié) pour les CRDs et gros bundles. Lekubectl apply --server-sideen shell n’est toléré que sur incompatibilité de parser documentée (casplatform-monitoring: enum- =non quotées rejetées par PyYAML, acceptées par le parser Go dekubectl) — on ne le convertit pas. - (d) Pré-check qui skip : un
commandà effet de bord est précédé d’un pré-check idempotent (modèleplatform-build-images:nerdctl manifest inspect→ bloc gardé parwhen: img_present.rc != 0) plutôt qu’exécuté inconditionnellement. - (e) Redémarrage de service TOUJOURS par handler (
notify), jamaissystemctl restartinline. Constat : déjà respecté partout sauf ledaemon_reloadinline d’etcd-backup→ à passer en handler notifié par lescopyd’unités. - (f) Aucune constante dépendant du déploiement codée en dur dans une
tâche. Application Ansible de la règle transverse posée par
l’ADR 0023 §3 (vraie pour Ansible,
shell ET Python) : toute valeur qui change selon le déploiement/topologie (IP,
devices
nvme1n1//dev/sd[a-z], tailles, comptes, seuils) vit dansdefaults/main.yaml(défaut = valeur d’exemple générique = PROD) surchargeable pargroup_vars; les constantes intrinsèques (chemins système, ports standard, versions épinglées ADR 0006) restent inline. Critère : « cette valeur changerait-elle d’un déploiement à l’autre ? »
Accepted. Met en œuvre #265 ; s’appuie sur l’ADR 0049 (patron de rôle) et l’ADR 0050 (reprise).
Conséquences
Section intitulée « Conséquences »- Hors-banc (diff additif / statiquement vérifiable, ansible-lint) :
check_mode: falseadditif (d),daemon_reload→ handler (e), et un job CIansible-playbook --syntax-check/--checkqui donne du sens aux annotationscheck_mode(sinon annotation morte non prouvée). - Banc-requis (change l’écriture sur le cluster ou le déclenchement d’un
handler) :
changed_whenpostfix (a) → scénario 22 ;server_side_applynouveaux (c) → managedFields ; pré-check CRD monitoring (d) → run. Suivis #265. - Garde-fou : la cible reste « 0 tâche mutante non gardée hors du rollback dédié », sous le profil production d’ansible-lint (déjà en CI).