Runbook de incidente noturno no AKS para líderes de TI em cuidados
Valide o JSON do Azure Monitor e separe decisões em incidentes noturnos de aplicações de cuidados.
Às 23h40, a responsável pelo turno da noite liga: a tela de agendamento da instituição abre, mas o registro de cuidados não é salvo. Existe um email do Azure, porém a passagem não informa o recurso alvo, a severidade nem se o alerta continua disparado. O rascunho para o fornecedor de TI contém até o nome de um residente. A liderança de operações e TI precisa interromper tanto o atraso da investigação quanto a disseminação secundária de dados pessoais.
Este artigo é para quem responde pelo aplicativo de agendamento e cuidados da instituição no Azure e pelo escalonamento noturno. Não é um manual para profissionais de cuidados na linha de frente. O objetivo é um runbook com uma linha do tempo compartilhada, mas com decisões de continuidade separadas da investigação do AKS.
Azure Kubernetes Service (AKS) é o serviço gerenciado de Kubernetes do Azure para implantar e administrar aplicações em contêineres. Kubernetes agenda, reinicia e escala grupos de contêineres; o Azure assume o trabalho operacional do plano de controle do AKS. Ainda assim, o Azure não decide o impacto na instituição, não investiga automaticamente cada workload nem define a ordem de contatos da madrugada.
Pontos principais
- Não converta
severitydo Azure diretamente em nível de incidente assistencial; avalie agendamento, registros, passagem e segurança separadamente. - Antes de usar Claude Code, sanitize o JSON do Common Alert Schema e valide localmente campos obrigatórios e dados pessoais diretos.
- Separe as tarefas de Claude Code, as decisões do operador Azure/TI e as decisões do responsável da instituição.
- Sem credenciais do Azure, o resultado é um teste do contrato de passagem, não um teste do AKS ou da entrega de alertas.
- Meça ROI com timestamps, rejeições e minutos de trabalho de incidentes comparáveis, sem percentuais inventados.
Transformar o incidente noturno em um único fluxo de passagem
Telefonemas, notificações do Azure, telas afetadas e tabela de contatos produzem versões diferentes quando ficam em notas separadas. A primeira ficha deve dizer: “busca de agendamento funciona”, “salvamento do registro falha”, “registro em papel ativado” e “próxima atualização às 00h10”. Estados de Pod, Node e Deployment vêm depois como evidência técnica.
Azure Monitor é o serviço unificado de observabilidade da Microsoft para coletar, analisar e agir sobre métricas, logs, traces e eventos de ambientes em nuvem e híbridos. Azure Monitor Common Alert Schema, ou esquema comum de alertas, é a estrutura JSON padronizada para consumir diferentes notificações do Azure Monitor. data.essentials leva metadados comuns, como severidade; data.alertContext varia conforme o sinal e oferece contexto para investigação.
O Microsoft Learn documenta severity de Sev0 a Sev4, signalType como Metric, Log ou Activity Log, e monitorCondition como Fired ou Resolved. alertTargetIDs é a lista de IDs do Azure Resource Manager atingidos pelo alerta. Esses campos ajudam a encaminhar a passagem, mas não decidem a segurança dos residentes, o uso de papel ou a recuperação operacional.
As fontes primárias verificadas em 23 de julho de 2026 são O que é AKS, Visão geral do Azure Monitor, Common Alert Schema, Monitorar AKS e Alertas do Service Health. Como leitura interna, consulte o guia de implantação com Kubernetes e a checklist de segurança do Claude Code.
flowchart TD
A["Receber alerta do Azure Monitor"] --> B["Salvar fixture JSON sanitizado"]
B --> C{"Validator local passou?"}
C -- "Não" --> D["Remover dados pessoais ou completar campos"]
D --> B
C -- "Sim" --> E["Claude Code organiza a passagem"]
E --> F["Azure/TI decide a investigação técnica"]
E --> G["A instituição decide a continuidade"]
F --> H["Unir evidências na próxima atualização"]
G --> H
H --> I{"As duas condições de encerramento foram cumpridas?"}
I -- "Não" --> H
I -- "Sim" --> J["Registrar a revisão pós-incidente"]
Service Health é outra fonte de evidência para notificações correspondentes às assinaturas, serviços, regiões e tipos configurados. Uma tela vazia não prova que a aplicação está saudável. Da mesma forma, um alerta AKS em Resolved não conclui a digitação dos papéis nem a conferência dos agendamentos.
O que Claude Code faz e o que as pessoas decidem
A tabela de passagem deve nomear entradas, saídas, proibições e aprovadores. Tratar Claude Code como responsável pela recuperação mistura diagnósticos sem prova e comandos de mudança na mesma conversa. Aqui ele apenas organiza evidências aprovadas.
Tarefas de Claude Code
- Extrair
severity,signalType,monitorCondition,alertTargetIDse horários de um fixture já validado. - Separar fatos confirmados, desconhecidos e decisões humanas pendentes; apontar horário de atualização ausente.
- Criar notas distintas para a instituição e o fornecedor sob o mesmo incident ID.
- Sugerir comandos de observação sem executá-los e informar evidências e permissões necessárias.
Decisões do operador Azure/TI
- Escolher a ordem de análise da regra, do alvo, da configuração de monitoramento, das mudanças recentes e da telemetria AKS.
- Decidir se coleta mais evidências no Azure Portal, Container insights, Log Analytics ou terminal autorizado.
- Aprovar ou recusar reinício, escala, rollback e escalonamento técnico.
- Decidir se
Resolvedbasta como evidência técnica ou se o monitoramento continua.
Decisões do responsável da instituição
- Pausar agendamentos, mudar registros para papel ou priorizar um fluxo de cuidados.
- Dirigir verificações de segurança, passagem, digitação posterior e comunicação com famílias ou terceiros.
- Aprovar o que pode ser compartilhado, o próximo informe interno e a declaração de recuperação.
- Definir quem conciliará registros ausentes ou agendamentos duplicados após a recuperação técnica.
Isto não é aconselhamento jurídico individualizado. Classificação, retenção, compartilhamento e notificação de dados pessoais devem seguir políticas, contratos e responsáveis da instituição.
Três casos de uso
Caso de uso 1: Passar uma falha noturna da API de agendamento
- Entrada: fixture Common Alert Schema sanitizado, verificação da tela, horário do incidente e próxima atualização.
- Saída: ficha separando IDs do Azure do impacto na instituição, dúvidas e pedido ao fornecedor.
- Revisão humana: Azure/TI aprova a investigação; a instituição aprova o canal alternativo e a conferência de duplicidades.
Sev1 sozinho não justifica fechar todos os canais. Falha de leitura e risco de escrita duplicada exigem ações diferentes. Claude Code separa observações e aprovações pendentes sem tomar a decisão.
Caso de uso 2: Escalonar demora ao salvar registros de cuidados
- Entrada: fixture válido, função afetada, quantidade sanitizada, intervalo e existência de release recente.
- Saída: nota técnica com campos de encaminhamento, reprodução sem dados diretos e evidências pendentes.
- Revisão humana: Azure/TI decide sobre logs e rollback; a instituição cuida do papel e da conciliação.
Não envie capturas ou logs com nomes de residentes ao Claude Code. O validator bloqueia chaves explícitas de identidade, emails e telefones, mas não reconhece todo nome sem rótulo, imagem ou identificador codificado. A revisão visual permanece uma aprovação humana.
Caso de uso 3: Encerrar a recuperação operacional após Resolved
- Entrada: fixture com
monitorCondition: "Resolved", conectividade, registros pendentes, duplicidades e histórico de contatos. - Saída: checklists separadas de encerramento técnico e operacional, trabalho restante e responsável da manhã.
- Revisão humana: Azure/TI encerra o monitoramento; a instituição declara recuperação após a conciliação.
No Common Alert Schema, Resolved significa que a condição que disparou o alerta desapareceu. Não confirma que o papel foi digitado nem que os retornos terminaram. Dois encerramentos impedem que a recuperação técnica esconda trabalho operacional.
Validator de passagem pronto para copiar
O validator abaixo usa apenas a biblioteca padrão do Node.js e lê o caminho JSON fornecido na linha de comando. Ele não entra no Azure e não chama AKS, Azure Monitor ou kubectl. Testa somente a forma documentada do Common Alert Schema e o contrato de sanitização deste 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);
}
}
Salve o fixture completo como sanitized-alert.json ao lado do validator. IDs, horários e nomes de regras são dados de teste, não resultados observados. customProperties é um ponto de extensão documentado; aqui deixa visível a declaração de sanitização.
{
"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"
}
}
}
Execute estes comandos exatos com Node.js 17 ou mais recente. O primeiro lê o fixture válido. O segundo prova a rejeição de dados pessoais diretos e de cada um dos quatro campos obrigatórios ausentes.
node validate-azure-alert-handoff.mjs sanitized-alert.json
node validate-azure-alert-handoff.mjs --self-test
Esta é a saída exata produzida pelo código e fixture publicados em 23 de julho de 2026, não uma estimativa.
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
Passar não prova configuração do Azure, entrega real, saúde do AKS ou procedimento de recuperação. Um teste conectado precisa do Common Alert Schema habilitado no Action Group, receptor, credenciais, rede, permissões e alerta de teste. Nenhuma credencial foi usada aqui; apenas o contrato documentado de passagem foi testado.
Armadilhas: um objeto fixo não é um teste operacional
A primeira falha é validar um objeto embutido no script e declarar a implementação pronta. Leitura de arquivo, JSON inválido, campos ausentes e saída de rejeição nunca rodam. A correção é ler um fixture local e executar sucesso e falhas em toda revisão do runbook.
A segunda falha é chamar o validator aprovado de teste de conectividade AKS. O erro é usar o mesmo nome para contrato de entrada e acesso à nuvem. Registre “handoff contract passed” e separe entrega, monitoramento e evidências AKS.
A terceira falha é mapear Sev0 a Sev4 diretamente para segurança de cuidados. A severidade do Azure e o impacto na instituição são escalas diferentes. Aprove separadamente severidade, agendamento, registros, segurança e papel.
A quarta falha é anunciar automaticamente Resolved como encerramento. A condição pode sumir e ainda haver registros pendentes. Mantenha o incident ID aberto até os dois encerramentos.
A quinta falha é tratar o validator como garantia contra dados pessoais. Padrões não detectam toda imagem, identificador opaco ou nome sem rótulo. Minimize entradas, revise texto livre e anexos e aplique a governança da instituição.
Medir ROI com incidentes comparáveis
Monte a tabela de ROI com incident ID, timestamps e minutos de trabalho. Compare faixas de severidade, horários noturnos e impactos semelhantes. Com poucos casos, mostre cada linha do tempo em vez de afirmar uma taxa.
| Métrica | Registro | Pergunta |
|---|---|---|
| Tempo de passagem para TI | Primeiro alerta até TI receber fixture válido | Quanto tempo se perde com defeitos do contrato? |
| Tempo de confirmação do impacto | Alerta até aprovação de agendamento, registros e passagem | Quantas idas e voltas existem entre técnica e operação? |
| Taxa de rejeição do fixture | Envios rejeitados ÷ todos os envios | Campos e sanitização viraram rotina? |
| Aceitação na primeira escalada | Casos iniciados sem pergunta ÷ todos os casos | A passagem basta para investigar? |
| Tempo manual | Minutos por função em transcrição, conferência e redigitação | Que trabalho resta à noite e pela manhã? |
Para expressar valor financeiro, multiplique minutos economizados por custos completos aprovados, some o retrabalho evitado aprovado e subtraia desenho, revisão, exercício e manutenção. Divida o benefício líquido pelo investimento. Sem linha de base, período e exclusões, apresente tempos e rejeições sem chamá-los de ROI.
Perguntas frequentes
P. Este validator conecta ao Azure Monitor ou AKS?
R. Não. Ele lê JSON local e não prova entrega, credenciais ou estado do cluster.
P. Por que exigir quatro campos de essentials?
R. O encaminhamento noturno precisa de severidade, tipo de sinal, estado e alvos. Nem todo campo do esquema vira obrigatório.
P. Passar prova que não há dados pessoais?
R. Não. Chaves explícitas, emails, telefones e nomes rotulados são rejeitados; imagens e texto livre exigem revisão.
P. Claude Code deve executar mudanças no Azure?
R. Não neste runbook. Azure/TI revisa permissões, impacto, rollback e aprovação e usa o processo existente.
P. Service Health vazio prova que AKS está saudável?
R. Não. Ele reflete critérios configurados e deve ser combinado com evidências de aplicação, workload, rede e monitoramento.
CTA de consultoria: incident runbook review
Na página de treinamento e consultoria ClaudeCodeLab, solicite uma “incident runbook review” para o fluxo noturno de agendamento ou registros. A entrega inclui comentários no runbook atual, contrato Common Alert Schema, tabela de decisão de três papéis, procedimento de teste e riscos pendentes. Leve apenas um alerta sanitizado, tabela de contatos e uma linha do tempo recente, sem credenciais ou dados pessoais.
Resultado realmente testado
Em 23 de julho de 2026, extraímos validate-azure-alert-handoff.mjs e sanitized-alert.json para uma pasta temporária e executamos os dois comandos mostrados. O fixture válido encerrou com código 0. O autoteste rejeitou dados pessoais diretos e a ausência de severity, signalType, monitorCondition e alertTargetIDs, totalizando cinco casos. As verificações do repositório também cobrem frontmatter, links internos, URLs oficiais, blocos de código e o slug comum em dez idiomas. Não usamos credenciais Azure; acesso real ao AKS, Action Group e entrega permanecem sem teste. Comece sanitizando um alerta da instituição e execute estes dois comandos como primeira etapa da revisão.
Artigos relacionados
Atendimento domiciliar: agilize registros de visita e instruções para cuidadores com Claude Code
Para coordenadores de atendimento domiciliar: agilize registros de visita e instruções de cuidador com IA. Inclui prompt e script.
Registros de cuidado em ILPI: organizar anotações e relatórios para famílias com Claude Code
Transforme anotações soltas de cuidado em texto legível e rascunhe o relatório à família, com prompt pronto e script de verificação.
Salão de beleza: como agilizar respostas de agendamento, avaliações e legendas com Claude Code
Para donos de salão: agilize agendamento, respostas a avaliações e legendas com Claude Code, com prompt pronto e script.
PDF grátis: cheatsheet do Claude Code
Informe seu e-mail e baixe uma página com comandos, hábitos de revisão e workflows seguros.
Cuidamos dos seus dados e não enviamos spam.
Sobre o autor
Masa
Engenheiro focado em workflows práticos com Claude Code.