Advanced (Mis à jour: 23/07/2026)

Runbook d'incident AKS de nuit pour responsables SI du médico-social

Validez le JSON Azure Monitor et séparez les décisions lors d'un incident nocturne d'application de soins.

Runbook d'incident AKS de nuit pour responsables SI du médico-social

À 23 h 40, la responsable de nuit appelle : l’écran de réservation s’ouvre, mais l’enregistrement du dossier de soins échoue. Un courriel Azure est arrivé, pourtant la transmission ne précise ni la ressource visée, ni la sévérité, ni si l’alerte est encore active. Le brouillon destiné au prestataire informatique contient même le nom d’un résident. La personne responsable des opérations et du SI doit arrêter à la fois le retard d’investigation et la diffusion secondaire de données personnelles.

Cet article s’adresse au responsable de l’application de réservation et de soins de l’établissement sur Azure, y compris de son escalade nocturne. Ce n’est pas un guide destiné aux professionnels de soins en première ligne. L’objectif est un runbook qui conserve une chronologie commune tout en séparant les décisions de continuité de l’établissement de l’investigation AKS.

Azure Kubernetes Service (AKS) est le service Kubernetes managé d’Azure pour déployer et gérer des applications conteneurisées. Kubernetes planifie, redémarre et met à l’échelle des groupes de conteneurs ; Azure prend en charge le plan de contrôle AKS. Azure ne décide toutefois pas de l’impact métier dans l’établissement, n’enquête pas automatiquement sur chaque workload et ne définit pas l’ordre des appels de nuit.

Points à retenir

  • Ne transformez pas directement la valeur Azure severity en niveau d’incident médico-social ; évaluez séparément réservation, dossiers, relève et sécurité.
  • Avant Claude Code, assainissez le JSON Common Alert Schema, puis contrôlez localement les champs requis et les données personnelles directes.
  • Séparez les tâches de Claude Code, les décisions de l’opérateur Azure/SI et celles du responsable d’incident de l’établissement.
  • Sans identifiants Azure, parlez d’un test du contrat de transmission, pas d’un test AKS ou de livraison d’alerte.
  • Mesurez le ROI avec des incidents comparables, leurs horodatages, rejets et minutes de travail, sans taux inventé.

Transformer l’incident nocturne en un seul flux de transmission

Lorsque appels, notifications Azure, écrans touchés et tableau de contacts sont dans des notes séparées, l’événement de 23 h 40 change selon l’interlocuteur. La première fiche doit indiquer : « recherche de réservation fonctionnelle », « enregistrement du dossier en échec », « support papier activé » et « prochaine mise à jour à 00 h 10 ». Les états Pod, Node et Deployment viennent ensuite comme preuves techniques.

Azure Monitor est le service unifié d’observabilité de Microsoft qui collecte, analyse et exploite métriques, journaux, traces et événements des environnements cloud et hybrides. Azure Monitor Common Alert Schema, ou schéma commun d’alerte, est la structure JSON normalisée pour consommer différents avis Azure Monitor. data.essentials porte les métadonnées communes comme la sévérité ; data.alertContext varie selon le signal et apporte le contexte d’investigation.

Microsoft Learn documente severity de Sev0 à Sev4, signalType avec Metric, Log ou Activity Log, et monitorCondition avec Fired ou Resolved. alertTargetIDs est la liste des identifiants Azure Resource Manager ciblés. Ces champs orientent une transmission, mais ne décident ni de la sécurité des résidents, ni du passage au papier, ni de la reprise métier.

Les sources primaires vérifiées le 23 juillet 2026 sont Présentation d’AKS, Vue d’ensemble d’Azure Monitor, Common Alert Schema, Superviser AKS et Alertes Service Health. Pour aller plus loin sur le site, consultez le guide de déploiement Kubernetes et la checklist de sécurité Claude Code.

flowchart TD
  A["Recevoir l'alerte Azure Monitor"] --> B["Enregistrer le fixture JSON assaini"]
  B --> C{"Le validator local réussit ?"}
  C -- "Non" --> D["Retirer les données ou compléter les champs"]
  D --> B
  C -- "Oui" --> E["Claude Code structure la transmission"]
  E --> F["Azure/SI décide de l'investigation"]
  E --> G["L'établissement décide de la continuité"]
  F --> H["Fusionner les preuves à la prochaine mise à jour"]
  G --> H
  H --> I{"Les deux clôtures sont remplies ?"}
  I -- "Non" --> H
  I -- "Oui" --> J["Consigner la revue post-incident"]

Service Health est une autre preuve pour les notifications correspondant aux abonnements, services, régions et types configurés. Une vue vide ne prouve pas que l’application fonctionne. De même, une alerte AKS Resolved ne termine pas la ressaisie des dossiers papier ni le contrôle des réservations.

Ce que Claude Code traite et ce que les personnes décident

Le tableau de transmission nomme entrées, sorties, interdictions et approbateurs. Donner à Claude Code la responsabilité du rétablissement mélange diagnostics non étayés et commandes de changement dans la même conversation. Ici, il organise uniquement les preuves approuvées.

Tâches de Claude Code

  • Extraire severity, signalType, monitorCondition, alertTargetIDs et les heures d’un fixture déjà validé.
  • Séparer faits confirmés, inconnues et décisions humaines en attente ; signaler l’absence d’heure de mise à jour.
  • Rédiger deux notes distinctes, établissement et prestataire, sous le même incident ID.
  • Proposer des commandes d’observation sans les exécuter, avec les preuves et autorisations nécessaires.

Décisions de l’opérateur Azure/SI

  • Choisir l’ordre de contrôle de la règle, de la cible, de la supervision, des changements récents et de la télémétrie AKS.
  • Décider d’obtenir d’autres preuves dans Azure Portal, Container insights, Log Analytics ou un terminal autorisé.
  • Approuver ou refuser redémarrage, mise à l’échelle, rollback et escalade technique.
  • Décider si Resolved suffit comme preuve technique ou si la surveillance continue.

Décisions du responsable d’incident de l’établissement

  • Suspendre les réservations, passer les dossiers sur papier ou prioriser un processus de soins.
  • Diriger contrôles de sécurité, relève, ressaisie et communications vers les familles ou partenaires.
  • Approuver les informations partageables, la prochaine communication et la déclaration de reprise métier.
  • Désigner qui rapproche les dossiers manquants ou réservations dupliquées après la reprise technique.

Ce contenu ne constitue pas un conseil juridique individualisé. Classification, conservation, transmission et notification des données personnelles relèvent des règles, contrats et responsables de l’établissement.

Trois cas d’usage

Cas d’usage 1 : transmettre une panne nocturne de l’API de réservation

  • Entrée : fixture Common Alert Schema assaini, contrôle d’écran, heure de l’incident et prochaine mise à jour.
  • Sortie : fiche séparant cibles Azure et impact établissement, inconnues et demande au prestataire.
  • Revue humaine : Azure/SI approuve l’investigation ; l’établissement approuve le canal de secours et le contrôle des doublons.

Sev1 ne justifie pas à lui seul la fermeture de tous les canaux. Une lecture impossible et un risque de double écriture réclament des décisions différentes. Claude Code sépare faits observés et validations attendues.

Cas d’usage 2 : escalader les retards d’enregistrement des dossiers

  • Entrée : fixture valide, fonction touchée, volume assaini, plage horaire et présence d’une version récente.
  • Sortie : note technique complète, conditions de reproduction sans données directes et preuves manquantes.
  • Revue humaine : Azure/SI décide des journaux et du rollback ; l’établissement gère papier et rapprochement.

N’envoyez pas à Claude Code une capture ou un log contenant un nom de résident. Le validator bloque les clés explicites, adresses mail et téléphones, mais pas tous les noms sans étiquette, images ou identifiants encodés. La revue visuelle reste une approbation humaine.

Cas d’usage 3 : clôturer la reprise métier après Resolved

  • Entrée : fixture avec monitorCondition: "Resolved", connectivité, dossiers en attente, doublons et historique des contacts.
  • Sortie : checklists séparées de clôture technique et métier, travaux restants et responsable du matin.
  • Revue humaine : Azure/SI clôt la surveillance ; l’établissement déclare la reprise après rapprochement.

Dans Common Alert Schema, Resolved indique que la condition à l’origine de l’alerte a disparu. Il ne confirme ni la ressaisie papier ni les rappels. Deux clôtures empêchent une reprise technique de masquer le travail opérationnel.

Validator de transmission prêt à copier

Le validator suivant utilise uniquement la bibliothèque standard Node.js et lit le fichier JSON donné en argument. Il ne se connecte pas à Azure et n’appelle ni AKS, ni Azure Monitor, ni kubectl. Il teste seulement la forme Common Alert Schema documentée et le contrat d’assainissement de ce runbook.

// validate-azure-alert-handoff.mjs
import { readFileSync } from "node:fs";

const REQUIRED = ["severity", "signalType", "monitorCondition", "alertTargetIDs"];
const ALLOWED = {
  severity: new Set(["Sev0", "Sev1", "Sev2", "Sev3", "Sev4"]),
  signalType: new Set(["Metric", "Log", "Activity Log"]),
  monitorCondition: new Set(["Fired", "Resolved"]),
};
const DIRECT_PERSONAL_DATA_KEYS = new Set([
  "residentname", "patientname", "carerecipientname", "serviceusername",
  "staffname", "employeename", "familyname", "guardianname",
  "phone", "phonenumber", "telephone", "mobile",
  "email", "emailaddress", "streetaddress", "postaladdress",
  "dateofbirth", "birthdate", "medicalrecordid", "carerecordid",
  "residentid", "patientid",
]);
const EMAIL = /\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}\b/i;
const PHONE = /(?:^|[^A-Za-z0-9])(?:\+\d{1,3}[ .-]?)?(?:\(\d{2,4}\)|\d{2,4})[ .-]\d{2,4}[ .-]\d{3,4}(?:$|[^A-Za-z0-9])/;
const LABELED_NAME = /(?:resident|patient|care recipient|staff|employee|family|guardian|利用者|入居者|患者|職員|家族)(?:\s+name|氏名|名)\s*[:=:]\s*\S+/iu;
const ARM_RESOURCE_ID_PATH = /^\$\.data\.essentials\.(?:alertId|alertRuleId|alertTargetIDs\[\d+\])$/;

function normalizeKey(key) {
  return key.replace(/[^a-z0-9]/gi, "").toLowerCase();
}

function findDirectPersonalData(value, path = "$", findings = []) {
  if (Array.isArray(value)) {
    value.forEach((item, index) => findDirectPersonalData(item, `${path}[${index}]`, findings));
    return findings;
  }
  if (value && typeof value === "object") {
    for (const [key, child] of Object.entries(value)) {
      const childPath = `${path}.${key}`;
      if (DIRECT_PERSONAL_DATA_KEYS.has(normalizeKey(key))) {
        findings.push(`${childPath} uses a prohibited direct-personal-data key`);
      }
      findDirectPersonalData(child, childPath, findings);
    }
    return findings;
  }
  if (typeof value === "string") {
    if (EMAIL.test(value)) findings.push(`${path} contains an email address`);
    if (!ARM_RESOURCE_ID_PATH.test(path) && PHONE.test(value)) {
      findings.push(`${path} contains a phone number`);
    }
    if (LABELED_NAME.test(value)) findings.push(`${path} contains a labeled person name`);
  }
  return findings;
}

export function validate(payload) {
  const errors = [];
  if (!payload || typeof payload !== "object" || Array.isArray(payload)) {
    throw new Error("payload must be a JSON object");
  }
  if (payload.schemaId !== "azureMonitorCommonAlertSchema") {
    errors.push('schemaId must be "azureMonitorCommonAlertSchema"');
  }

  const essentials = payload.data?.essentials;
  if (!essentials || typeof essentials !== "object" || Array.isArray(essentials)) {
    errors.push("data.essentials must be an object");
  } else {
    for (const field of REQUIRED) {
      if (!(field in essentials)) errors.push(`missing data.essentials.${field}`);
    }
    for (const [field, allowed] of Object.entries(ALLOWED)) {
      if (field in essentials && !allowed.has(essentials[field])) {
        errors.push(`data.essentials.${field} has an undocumented value`);
      }
    }
    if ("alertTargetIDs" in essentials) {
      if (!Array.isArray(essentials.alertTargetIDs) ||
          essentials.alertTargetIDs.length === 0 ||
          essentials.alertTargetIDs.some((id) => typeof id !== "string" || id.trim() === "")) {
        errors.push("data.essentials.alertTargetIDs must be a non-empty string array");
      }
    }
  }

  errors.push(...findDirectPersonalData(payload));
  if (errors.length > 0) throw new Error(errors.join("; "));
  return true;
}

function loadJson(filePath) {
  return JSON.parse(readFileSync(filePath, "utf8"));
}

function runSelfTest() {
  const base = loadJson("sanitized-alert.json");
  validate(base);
  const cases = [
    ["direct personal data", (p) => { p.data.customProperties.residentName = "Example Resident"; }],
    ["missing severity", (p) => { delete p.data.essentials.severity; }],
    ["missing signalType", (p) => { delete p.data.essentials.signalType; }],
    ["missing monitorCondition", (p) => { delete p.data.essentials.monitorCondition; }],
    ["missing alertTargetIDs", (p) => { delete p.data.essentials.alertTargetIDs; }],
  ];
  let rejected = 0;
  for (const [label, mutate] of cases) {
    const candidate = structuredClone(base);
    mutate(candidate);
    try {
      validate(candidate);
      console.error(`FAIL self-test: accepted ${label}`);
      process.exitCode = 1;
    } catch {
      console.log(`PASS self-test: rejected ${label}`);
      rejected += 1;
    }
  }
  if (!process.exitCode) console.log(`PASS self-test: ${rejected} rejection cases`);
}

if (process.argv[2] === "--self-test") {
  runSelfTest();
} else {
  const filePath = process.argv[2];
  if (!filePath) {
    console.error("Usage: node validate-azure-alert-handoff.mjs <fixture.json> | --self-test");
    process.exit(2);
  }
  try {
    validate(loadJson(filePath));
    console.log(`PASS fixture: ${filePath}`);
  } catch (error) {
    console.error(`FAIL fixture: ${error.message}`);
    process.exit(1);
  }
}

Enregistrez le fixture complet sous sanitized-alert.json à côté du validator. Les ID, heures et noms de règle sont des données de test, pas des résultats observés. customProperties est un point d’extension documenté ; il rend ici la déclaration d’assainissement visible.

{
  "schemaId": "azureMonitorCommonAlertSchema",
  "data": {
    "essentials": {
      "alertId": "/subscriptions/00000000-0000-4000-8000-000000000000/providers/Microsoft.AlertsManagement/alerts/11111111-1111-4111-8111-111111111111",
      "alertRule": "care-api-availability",
      "alertRuleId": "/subscriptions/00000000-0000-4000-8000-000000000000/resourceGroups/rg-care-prod/providers/microsoft.insights/metricAlerts/care-api-availability",
      "severity": "Sev1",
      "signalType": "Metric",
      "monitorCondition": "Fired",
      "monitoringService": "Platform",
      "alertTargetIDs": [
        "/subscriptions/00000000-0000-4000-8000-000000000000/resourceGroups/rg-care-prod/providers/Microsoft.ContainerService/managedClusters/aks-care-prod"
      ],
      "configurationItems": [
        "aks-care-prod"
      ],
      "originAlertId": "sanitized-night-incident-001",
      "firedDateTime": "2026-07-23T14:40:00Z",
      "description": "The production booking and care-record API crossed its approved availability threshold.",
      "essentialsVersion": "1.0",
      "alertContextVersion": "1.0"
    },
    "alertContext": {
      "properties": null
    },
    "customProperties": {
      "environment": "production",
      "service": "booking-care-api",
      "sanitized": "true",
      "runbook": "night-incident-v1"
    }
  }
}

Exécutez ces commandes exactes avec Node.js 17 ou plus récent. La première lit le fixture valide. La seconde prouve le rejet des données personnelles directes et de chacun des quatre champs requis absents.

node validate-azure-alert-handoff.mjs sanitized-alert.json
node validate-azure-alert-handoff.mjs --self-test

Voici la sortie exacte produite par le code et le fixture publiés le 23 juillet 2026, et non une estimation.

PASS fixture: sanitized-alert.json
PASS self-test: rejected direct personal data
PASS self-test: rejected missing severity
PASS self-test: rejected missing signalType
PASS self-test: rejected missing monitorCondition
PASS self-test: rejected missing alertTargetIDs
PASS self-test: 5 rejection cases

Un succès ne prouve ni la configuration Azure, ni la livraison réelle, ni l’état AKS, ni la procédure de reprise. Un test connecté requiert Common Alert Schema activé sur l’Action Group, un récepteur, des identifiants, le réseau, les droits et une alerte de test. Aucun identifiant n’a été utilisé ici : seul le contrat de transmission documenté a été testé.

Pièges : ne pas appeler un objet fixe un test d’exploitation

Premier piège : valider un objet intégré au script et annoncer une implémentation. La lecture de fichier, le JSON invalide, les champs absents et les sorties d’échec ne sont jamais exercés. La correction consiste à lire un fixture local et exécuter succès et échecs lors de chaque revue du runbook.

Deuxième piège : appeler le succès du validator un test de connexion AKS. La cause est le même nom pour le contrat d’entrée et l’accès cloud. Consignez « handoff contract passed » et séparez livraison, supervision et preuves AKS.

Troisième piège : convertir directement Sev0 à Sev4 en niveaux de sécurité des soins. Ce sont deux échelles. Faites approuver séparément sévérité Azure, impact réservation, impact dossier, sécurité et papier.

Quatrième piège : diffuser automatiquement Resolved comme clôture. La condition peut disparaître tandis que des dossiers restent à saisir. Gardez l’incident ID ouvert jusqu’aux deux clôtures.

Cinquième piège : considérer le validator comme garantie d’absence de données personnelles. Les motifs ne voient pas toute image, tout identifiant opaque ou nom sans étiquette. Réduisez les entrées, relisez texte libre et pièces jointes, puis appliquez la gouvernance de l’établissement.

Mesurer le ROI sur des incidents comparables

Construisez le tableau à partir des incident ID, horodatages et minutes. Comparez des plages de sévérité, horaires nocturnes et impacts proches. Avec peu d’incidents, présentez chaque chronologie sans affirmer un taux.

IndicateurMéthodeQuestion
Temps de transmission SIPremière alerte jusqu’au fixture valide reçuQuelle attente vient du contrat ?
Temps de confirmation d’impactAlerte jusqu’à validation réservation, dossier et relèveCombien d’allers-retours entre technique et métier ?
Taux de rejet du fixtureSoumissions rejetées ÷ toutes les soumissionsChamps et assainissement deviennent-ils habituels ?
Acceptation au premier envoiEscalades lancées sans question ÷ toutesLa transmission suffit-elle à enquêter ?
Temps manuelMinutes par rôle pour recopier, contrôler et ressaisirQuel travail reste la nuit et le matin ?

Pour une valeur financière, multipliez les minutes gagnées par les coûts chargés approuvés, ajoutez la reprise évitée validée, puis retirez conception, revue, exercice et maintenance. Divisez le bénéfice net par l’investissement. Sans référence, période et exclusions, publiez les temps et rejets sans les nommer ROI.

Questions fréquentes

Q. Ce validator se connecte-t-il à Azure Monitor ou AKS ?

R. Non. Il lit un JSON local et ne prouve ni livraison, ni identifiants, ni état du cluster.

Q. Pourquoi exiger ces quatre champs essentials ?

R. Le routage nocturne a besoin de la sévérité, du signal, de l’état et des cibles. Tous les champs Common Alert Schema ne deviennent pas obligatoires.

Q. Un succès garantit-il l’absence de données personnelles ?

R. Non. Les clés explicites, mails, téléphones et noms étiquetés sont rejetés ; images et texte libre restent à vérifier.

Q. Claude Code doit-il exécuter des changements Azure ?

R. Pas dans ce runbook. Azure/SI vérifie droits, impact, rollback et approbation, puis utilise la procédure existante.

Q. Service Health vide prouve-t-il qu’AKS fonctionne ?

R. Non. Il reflète des critères configurés et doit être croisé avec l’application, les workloads, le réseau et la supervision.

CTA de conseil : incident runbook review

Sur la page formation et conseil ClaudeCodeLab, demandez une « incident runbook review » pour le parcours nocturne de réservation ou de dossier de soins. Le livrable comprend commentaires sur le runbook actuel, contrat Common Alert Schema, tableau de décision des trois rôles, procédure de test et risques non résolus. Apportez uniquement une alerte assainie, le tableau de contacts et une chronologie récente, sans identifiants ni données personnelles.

Résultat réellement testé

Le 23 juillet 2026, nous avons extrait validate-azure-alert-handoff.mjs et sanitized-alert.json dans un dossier temporaire, puis exécuté les deux commandes affichées. Le fixture valide a terminé avec le code 0. L’autotest a rejeté les données personnelles directes et l’absence de severity, signalType, monitorCondition et alertTargetIDs, soit cinq cas. Les contrôles du dépôt couvrent aussi frontmatter, liens internes, URL officielles, blocs de code et slug partagé par dix langues. Aucun identifiant Azure n’a été utilisé ; l’accès AKS, l’Action Group et la livraison réelle restent non testés. Commencez par assainir une alerte de l’établissement et lancez ces deux commandes comme première étape de la revue.

#claude-code #etablissement-de-soins #aks #azure-monitor #gestion-incident
Gratuit

PDF gratuit: cheatsheet Claude Code

Saisissez votre email et téléchargez une page avec commandes, habitudes de review et workflow sûr.

Nous protégeons vos données et n'envoyons pas de spam.

Masa

À propos de l'auteur

Masa

Ingénieur spécialisé dans les workflows pratiques avec Claude Code.