Workflows d’approbation dans Microsoft Fabric — listes dynamiques, portes AND et OR

Bienvenue dans la série Beyond ETL dédiée à Microsoft Fabric

Innovation Bulb Icon Sign Symbol

Les pipelines Fabric ne sont plus de simples outils de mouvement de données. Avec l’activité Approval, ils deviennent des orchestrateurs de workflow mêlant automatisation et validation humaine. Microsoft l’a formalisé dans cet article de blog : les pipelines évoluent vers des ponts entre systèmes, équipes et décisions. Cet article couvre le cas de la validation humaine intégrée dans un pipeline de données.

L’activité Approval de Fabric permet d’insérer une étape de validation humaine directement dans un pipeline, sans outil externe. Le traitement s’arrête, une notification est envoyée par mail, et ne reprend que si l’approbateur valide.

Les trois patterns d’approbation

Cet article couvre trois patterns, du plus simple au plus complet :

  • Approbateur unique — un seul valideur, pas de boucle
  • Porte AND — tous les approbateurs d’une liste doivent valider
  • Porte OR — un seul approbateur suffit

L’implémentation qui importe vraiment n’est pas de savoir comment câbler une activité Approval — c’est de savoir comment rendre dynamique la liste des approbateurs. Une liste codée en dur dans le pipeline est un anti-pattern : elle impose de modifier le pipeline à chaque changement d’organisation, elle n’est pas auditable, et elle ne s’adapte pas aux données.

Workflow Approval Fabric

Comportement de l’activité Approval — contraintes à connaître

Avant de construire quoi que ce soit, deux comportements à assimiler.

En cas de rejet, l’activité Approval fail directement. Elle ne retourne pas un statut Approved / Rejected dans son output — elle échoue. Cette contrainte détermine l’ensemble de l’architecture : la porte AND en découle naturellement, la porte OR nécessite un contournement.

Le lien d’approbation est universel. N’importe quel compte ayant accès au workspace Fabric peut valider via le lien reçu par mail, indépendamment du destinataire. La liste d’approbateurs est une liste de destinataires de notifications — pas une contrainte de sécurité.

Workflow Approval Fabric

Ce comportement a été vérifié par expérimentation : un compte différent du destinataire peut valider via le lien.

Workflow Approval Fabric

Un compte sans accès au workspace, en revanche, ne peut pas valider.

Workflow Approval Fabric
L’identité du validateur n’est pas enregistrée. L’output de l’activité ne contient pas l’identité de la personne ayant cliqué. Un audit trail fiable nécessite un webhook ou une activité Web complémentaire.

Utiliser une liste d’approbateurs dynamique

Le problème de l’activité

La version naïve définit l’approver unique en dur dans le pipeline :

"approvers": "manager@entreprise.com"
  

Créer une liste d’approbateurs dynamique

Dès que l’organisation change — un manager part, un périmètre se réorganise — il faut modifier le pipeline. Sur une plateforme avec plusieurs circuits de validation, c’est rapidement ingérable.

La solution : Lookup sur une table de configuration

La liste d’approbateurs est stockée dans une table (Lakehouse ou Warehouse) et récupérée dynamiquement au démarrage du pipeline via une activité Lookup.

Workflow Approval Fabric

Le ForEach itère ensuite sur la sortie de GetApprovers (@activity('GetApprovers').output.value), directement.

Avantage clé : modifier le circuit de validation revient à mettre à jour une ligne dans une table. Aucun pipeline à modifier, aucun déploiement nécessaire.

Porte AND — tous les approbateurs doivent valider

La porte AND exploite le comportement natif de l’activité : si un approbateur rejette, l’activité fail. Dans un ForEach, si une itération échoue, le ForEach entier échoue. Le traitement aval ne s’exécute donc que si tous ont approuvé — sans logique supplémentaire.

[Lookup → liste dynamique]
   ↓
ForEach
   └── Approval → fail si rejet
   ↓ [Succeeded]
Traitement aval
    
{
 "name": "ForEachApprover",
 "type": "ForEach",
 "typeProperties": {
   "items": { "value": "@activity('GetApprovers').output.value", "type": "Expression" },
   "activities": [
     {
       "name": "ApprovalRequest",
       "type": "Approval",
       "policy": { "timeout": "0.12:00:00", "retry": 0 },
       "typeProperties": {
         "operationType": "ApprovalMail",
         "approvers": { "value": "@item().approver_email", "type": "Expression" },
         "approvalRequestTitle": "Validation requise"
       },
       "externalReferences": { "connection": "GUID connexion mail>" }
     }
   ]
 }
}
    
Workflow Approval Fabric

Porte OR — un seul approbateur suffit

Le contournement consiste à capturer les deux issues (Succeeded et Failed) via deux AppendVariable distincts, puis évaluer la liste résultante dans un IfCondition après le ForEach.

Point critique : le ForEach doit être raccordé à l’IfCondition avec la condition Completed — pas Succeeded. Sans ça, si au moins un approbateur rejette, le ForEach est en échec et l’IfCondition n’est jamais atteinte.

[Lookup → liste dynamique]
   ↓
ForEach (parallèle)
   ├── Approval
   │    ├── Succeeded → AppendVariable → approvedList
   │    └── Failed    → AppendVariable → rejectedList
   ↓ [Completed]
IfCondition
   ├── @greater(length(variables('approvedList')), 0)→ continuer
   └── stopper / notifier
    
Workflow Approval Fabric
{
 "name": "OuPorteDynamique",
 "type": "IfCondition",
 "dependsOn": [
   { "activity": "ForEachApprover", "dependencyConditions": ["Completed"] }
 ],
 "typeProperties": {
   "expression": {
     "value": "@greater(length(variables('approvedList')), 0)",
     "type": "Expression"
   }
 }
}
    
Variables nécessaires :
"variables": {
 "approvedList": { "type": "Array" },
 "rejectedList": { "type": "Array" }
}

Limites et points d’attention

  • Race condition sur AppendVariable en parallèle
  • Expiration du lien d’approbation
  • Durée totale élevée avec plusieurs approbateurs
  • Pas d’audit trail natif
  • Lien valide pour tout utilisateur du workspace

Série Beyond ETL — Microsoft Fabric transforme les pipelines en systèmes de décision hybrides entre data et humain.

Article rédigé par Romain Data Engineer Fabric

Le blog