Infrastructure

Azure Monitor : déployer une transformation DCR sans perdre la télémétrie

Un runbook de production pour canaryer une transformation KQL dans une Data Collection Rule, comparer volumes et schémas, détecter les rejets puis valider ou rollbacker sans trou d'observabilité.

03 août 2026 azureazure-monitordata-collection-ruledcrlog-analyticskqlobservabilitytelemetrycanaryautomationrunbookrollbackproduction

Une équipe réduit le coût de ses logs en supprimant des champs inutiles dans une Data Collection Rule Azure Monitor. La transformation KQL est valide dans un éditeur, le déploiement réussit et la table continue de recevoir des lignes. Quelques heures plus tard, un incident révèle que le champ utilisé pour corréler les requêtes a disparu et qu’une catégorie de messages n’arrive plus du tout.

Une transformation DCR est une étape du pipeline de collecte, pas une simple requête de lecture. Elle peut filtrer des enregistrements, renommer des colonnes, changer des types ou produire un schéma incompatible avec la destination. Ce runbook propose un déploiement par canary : figer le contrat de télémétrie, mesurer une référence, tester la transformation sur des échantillons, isoler une source, comparer ancien et nouveau flux, puis conserver ou rollbacker la DCR.

Figer le contrat avant de toucher au flux

Le changement doit nommer ce qui peut disparaître et ce qui doit rester exploitable. « Réduire le volume » n’est pas un critère de succès suffisant.

yaml dcr-change-contract.yml
change:
dcr_current: dcr-app-prod-v12
dcr_candidate: dcr-app-prod-v13
stream: Custom-AppRuntime_CL
destination: law-platform-prod
canary_source: vm-app-canary-01
observation_window: 60m

must_preserve:
- TimeGenerated
- _ResourceId
- CorrelationId
- Severity
- MessageType

allowed_change:
- drop DebugPayload
- keep only approved MessageType values

evidence:
- dcr_json_before_after
- association_before_after
- source_and_destination_row_counts
- null_and_type_checks
- ingestion_latency
- rejected_or_missing_record_signals
- rollback_owner_and_deadline

Conservez le JSON de la DCR active, ses associations, le schéma du stream et les alertes qui lisent la table. Une colonne apparemment secondaire peut être une clé de jointure dans une règle KQL, un workbook ou un runbook d’incident.

Mesurer une référence qui distingue absence et retard

Avant le changement, mesurez le volume, la répartition métier, les champs obligatoires et la latence d’ingestion sur une fenêtre comparable. Une simple courbe de lignes ne détecte ni un type cassé ni la disparition d’une catégorie rare.

kusto 01-dcr-baseline.kql
let StartTime = datetime(2026-08-03T05:00:00Z);
let EndTime = datetime(2026-08-03T06:00:00Z);
Custom_AppRuntime_CL
| where TimeGenerated between (StartTime .. EndTime)
| summarize
  Rows=count(),
  Sources=dcount(_ResourceId),
  MissingCorrelation=countif(isempty(CorrelationId)),
  MissingSeverity=countif(isempty(Severity)),
  P95IngestionDelay=percentile(ingestion_time() - TimeGenerated, 95)
by MessageType, bin(TimeGenerated, 5m)
| order by TimeGenerated asc

Ajoutez un signal synthétique émis à intervalle connu par la source canary. Il doit contenir une valeur de corrélation unique et traverser le même chemin que les événements réels. Son absence donne une preuve plus nette qu’une baisse de volume sur une application naturellement variable.

Relire le chemin complet de la DCR

Une DCR relie des sources, des streams, des transformations et des destinations. Vérifiez le nom du stream entrant, le transformKql, le stream de sortie et le schéma attendu par la table. Une transformation correcte sur un échantillon peut rester incompatible avec le stream de sortie.

bash 02-freeze-dcr-state.sh
SUBSCRIPTION_ID="<subscription-id>"
RESOURCE_GROUP="rg-observability-prod"
DCR_NAME="dcr-app-prod-v12"
API_VERSION="<supported-api-version>"

az rest --method get --url "https://management.azure.com/subscriptions/$SUBSCRIPTION_ID/resourceGroups/$RESOURCE_GROUP/providers/Microsoft.Insights/dataCollectionRules/$DCR_NAME?api-version=$API_VERSION" --output json > dcr-before.json

az resource list --resource-group "$RESOURCE_GROUP" --resource-type Microsoft.Insights/dataCollectionRuleAssociations --output json > dcr-associations-before.json

Choisissez une version d’API déjà approuvée dans votre IaC ou votre pipeline. Le runbook ne doit pas introduire une nouvelle version d’API en même temps que la transformation : cela ajouterait une seconde variable au diagnostic.

Tester la transformation comme un contrat de données

Construisez des échantillons représentant chaque catégorie, les champs absents, les valeurs longues et les types inattendus. Le test doit prouver le résultat ligne par ligne, pas seulement l’absence d’erreur de syntaxe.

kusto transform-candidate.kql
source
| where MessageType in ("request", "dependency", "exception", "audit")
| extend
  CorrelationId = tostring(CorrelationId),
  Severity = tostring(Severity),
  MessageType = tostring(MessageType)
| project
  TimeGenerated,
  _ResourceId,
  CorrelationId,
  Severity,
  MessageType,
  Message

Traitez explicitement les entrées non conformes. Si une valeur inconnue doit être conservée pour investigation, routez-la vers un chemin de quarantaine prévu par l’architecture ou bloquez la mise en production. La supprimer silencieusement avec un filtre transforme une erreur de données en absence de preuve.

text dcr-transform-test-cases.txt
Cas nominaux
Une ligne par MessageType autorise
CorrelationId et _ResourceId conserves
Types conformes au stream de sortie

Cas de bord
CorrelationId absent
MessageType inconnu
Severity numerique au lieu de texte
Message vide ou tres long
Horodatage en retard

Bloquer le deploiement si
Une ligne obligatoire est filtree
Une colonne utilisee par une alerte disparait
Le type de sortie ne correspond pas au schema
Le comportement d'une valeur inconnue n'est pas defini

Cloner la DCR et limiter le canary à une source

Ne remplacez pas la DCR partagée pour tester. Créez une version candidate avec un nom et un artefact IaC distincts, puis associez uniquement une source canary. Évitez qu’une même source envoie simultanément le même stream vers les deux règles si cela duplique les données ou fausse les comparaisons.

Le canary doit produire un trafic représentatif mais réversible. Pour une flotte de VM, une seule machine ou un petit groupe suffit. Pour un service distribué, utilisez une instance dédiée ou un environnement dont les événements sont identifiables. Documentez l’association exacte avant et après le basculement.

yaml dcr-canary-plan.yml
steps:
- deploy candidate DCR without association
- compare candidate JSON with current DCR
- associate only vm-app-canary-01 with candidate
- emit one synthetic event every five minutes
- observe for at least one full alert evaluation cycle
- compare counts, categories, required fields and latency
- expand in bounded batches or restore previous association

stop_conditions:
- synthetic event missing
- source sends duplicate records
- required field becomes null
- unexpected MessageType disappears
- ingestion latency exceeds the agreed baseline
- alert or workbook query fails

Comparer le flux attendu au flux réellement ingéré

Le meilleur contrôle compare un compteur côté producteur ou collecteur avec les lignes reçues. Si ce compteur n’existe pas, utilisez le signal synthétique, les logs de l’agent de collecte, les métriques de la ressource et les catégories observées avant le changement.

kusto 03-validate-dcr-canary.kql
let CanaryResource = "/subscriptions/<id>/resourceGroups/rg-app-prod/providers/Microsoft.Compute/virtualMachines/vm-app-canary-01";
let StartTime = datetime(2026-08-03T06:15:00Z);
Custom_AppRuntime_CL
| where TimeGenerated >= StartTime
| where _ResourceId =~ CanaryResource
| summarize
  Rows=count(),
  Correlations=dcount(CorrelationId),
  MissingCorrelation=countif(isempty(CorrelationId)),
  MissingResource=countif(isempty(_ResourceId)),
  P95IngestionDelay=percentile(ingestion_time() - TimeGenerated, 95)
by MessageType, bin(TimeGenerated, 5m)
| order by TimeGenerated asc

Relancez aussi les requêtes des alertes et workbooks critiques sur la période canary. Une transformation peut conserver les lignes tout en cassant une jointure, une extraction JSON ou une condition fondée sur l’ancienne casse d’une valeur.

Étendre avec un gate, rollbacker par réassociation

Étendez la DCR candidate par petits lots seulement si le signal synthétique est continu, les catégories attendues restent présentes, les champs obligatoires sont renseignés, la latence reste dans la référence et les consommateurs KQL fonctionnent. Capturez les mêmes preuves après chaque lot.

Le rollback consiste à réassocier les sources à la DCR précédente, puis à confirmer le retour du signal synthétique et des catégories attendues. Ne supprimez pas immédiatement la DCR candidate : conservez son JSON, ses associations finales et la fenêtre exacte d’exposition pour l’analyse. Ne rejouez des événements que si la source ou un buffer les a réellement conservés et si le rejeu est idempotent.

text dcr-production-decision.txt
Conserver et etendre
Signal synthetique continu
Volumes explicables par categorie
Champs et types obligatoires preserves
Alertes et workbooks valides
Latence dans la reference acceptee

Rollbacker
Ligne ou categorie attendue absente
Schema ou requete consommatrice casse
Duplications apres association
Latence ou rejets non expliques
Impossible de comparer source et destination

Apres rollback
Restaurer l'association precedente
Prouver le retour du signal canary
Conserver les artefacts de la DCR candidate
Qualifier la fenetre de donnees potentiellement perdues
Corriger le contrat avant un nouvel essai

Conclusion

Une transformation DCR n’est validée ni par un déploiement ARM réussi ni par quelques lignes visibles dans Log Analytics. Elle est validée lorsque le canary prouve que les événements attendus arrivent une seule fois, avec le bon schéma, dans le délai convenu, et que les alertes continuent de produire la même décision.

Le gate de production est simple : étendre uniquement avec des preuves comparables côté source et destination. Au premier signal manquant ou schéma ambigu, restaurez l’association précédente, mesurez la fenêtre affectée et corrigez la transformation avant de retenter.