Initial addition of ms-ai-architect plugin to the open-source marketplace. Private content excluded: orchestrator/ (Linear tooling), docs/utredning/ (client investigation), generated test reports and PDF export script. skill-gen tooling moved from orchestrator/ to scripts/skill-gen/. Security scan: WARNING (risk 20/100) — no secrets, no injection found. False positive fixed: added gitleaks:allow to Python variable reference in output-validation-grounding-verification.md line 109. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
22 KiB
Failover Testing for AI Services
Last updated: 2026-02 Status: GA Category: Business Continuity & Disaster Recovery
Introduksjon
Failover-testing er en kritisk men ofte forsoemmt del av disaster recovery for AI-tjenester. En DR-plan som ikke er testet er i praksis ingen plan -- den gir en falsk trygghet som kan forsterke konsekvensene av et reelt utfall. Microsoft anbefaler eksplisitt a gjennomfoere regelmessige failover-drills for a validere at resiliens-mekanismer fungerer som forventet, og at teamet er i stand til a haandtere en krise effektivt.
For AI-tjenester er failover-testing spesielt utfordrende av flere grunner. For det foerste er AI-inferens ofte tilstandsloest (stateless), men konteksten rundt -- samtalehistorikk, agent-tilstand, RAG-indekser -- er hoyst tilstandsfull. En vellykket failover av selve inferens-endepunktet betyr lite hvis samtalehistorikken gaar tapt eller kunnskapsbasen ikke er tilgjengelig i failover-regionen. For det andre har AI-tjenester kvotebegrensninger per region, saa en failover kan resultere i lavere kapasitet hvis sekundaerregionen har mindre kvote. For det tredje bruker mange AI-loesninger asynkrone pipelines (batch-prosessering, evaluering, fine-tuning) som har andre failover-moenstre enn sanntids-inferens.
Denne referansen dekker planlagte failover-testscenarier, validering og overvaking under failover, suksesskriterier og akseptanseterskel, dokumentasjon og laerdommer, samt regelmessig testplanlegging og frekvens. Alt er forankret i Microsofts veiledning for chaos engineering, Azure Chaos Studio, og Well-Architected Framework for reliability testing.
Planlagte failover-testscenarier
Scenariokatalog for AI-tjenester
Failover-tester boer dekke flere niva -- fra enkeltkomponent til fullstendig regional failover:
| Nivaa | Scenario | Beskrivelse | Kompleksitet | Risiko |
|---|---|---|---|---|
| L1 | Enkelt AOAI-endepunkt utilgjengelig | Simuler 429/503 fra ett Azure OpenAI-endepunkt | Lav | Lav |
| L2 | Cosmos DB regional failover | Bytt skriveregion for agentdata | Middels | Middels |
| L3 | Full gateway-failover | Ruter all trafikk via sekundaer APIM | Middels | Middels |
| L4 | AI Search utilgjengelig | RAG-indeks nede, test fallback | Middels | Lav |
| L5 | Komplett regional failover | All AI-infrastruktur bytter region | Hoey | Hoey |
| L6 | Korrupt data / utilsiktet sletting | Gjenopprett fra backup | Hoey | Middels |
Scenario L1: Azure OpenAI endepunkt-failover
Formal: Verifisere at APIM-gatewayen korrekt ruter trafikk til sekundaert endepunkt nar primaert returnerer feil.
Fremgangsmate:
1. Forutsetninger:
- APIM konfigurert med backend pool (Norway East primaer, Sweden Central sekundaer)
- Overvaking aktiv (Application Insights, Azure Monitor)
- Lastetest kjoerer for a generere trafikk
2. Feilinjeksjon:
- Metode A: APIM policy-endring (fjern primaer backend fra pool)
- Metode B: Azure Chaos Studio eksperiment
- Metode C: Nettverksregel som blokkerer trafikk til primaer
3. Forventet oppfoersel:
- Gateway returnerer 429/503 fra primaer backend
- Circuit breaker trigger innen < 5 sekunder
- Trafikk rutes automatisk til sekundaer backend
- Sluttbrukere opplever < 10 sekunder forsinkelse
4. Validering:
- Alle API-kall returnerer 200 innen 30 sekunder
- Latens stabiliserer seg innen 60 sekunder
- Ingen tapt kontekst for pagaende samtaler (med session affinity)
APIM policy for simulert feil:
<!-- Midlertidig policy for failover-test: simuler 503 fra primaer -->
<policies>
<inbound>
<base />
<choose>
<when condition="@(context.Request.Headers.GetValueOrDefault("X-Failover-Test","") == "active")">
<!-- Under test: fjern primaer fra backend pool -->
<set-backend-service backend-id="openai-secondary-only" />
</when>
<otherwise>
<set-backend-service backend-id="openai-backend-pool" />
</otherwise>
</choose>
</inbound>
</policies>
Scenario L2: Cosmos DB failover
Formal: Verifisere at agentdata er tilgjengelig etter Cosmos DB regional failover.
Fremgangsmate med Azure Chaos Studio:
{
"type": "Microsoft.Chaos/experiments",
"name": "cosmos-failover-test",
"location": "norwayeast",
"properties": {
"steps": [
{
"name": "Failover-Cosmos-DB",
"branches": [
{
"name": "cosmos-branch",
"actions": [
{
"type": "continuous",
"name": "urn:csci:microsoft:cosmosDB:failover/1.0",
"duration": "PT10M",
"parameters": [
{
"key": "readRegion",
"value": "Norway East"
}
],
"selectorId": "cosmos-target"
}
]
}
]
}
],
"selectors": [
{
"id": "cosmos-target",
"type": "List",
"targets": [
{
"id": "/subscriptions/{sub-id}/resourceGroups/rg-ai-prod/providers/Microsoft.DocumentDB/databaseAccounts/svv-ai-cosmos/providers/Microsoft.Chaos/targets/Microsoft-CosmosDB",
"type": "ChaosTarget"
}
]
}
]
}
}
Forventet oppfoersel:
- Cosmos DB bytter skriveregion fra Norway East til Sweden Central
- Lesning kan ha kortvarig hoeyre latens under failover
- Agentsamtaler kan fortsette uten datatap
- Failover fullfores innen < 5 minutter
Scenario L3: Full gateway-failover
Formal: Verifisere at all AI-trafikk kan betjenes fra sekundaer gateway-region.
Testoppfoersel:
1. Start med normal trafikk gjennom APIM i Norway East
2. Simuler at APIM i Norway East er utilgjengelig:
- DNS-endring: Pek gateway-FQDN til Sweden Central
- Eller: Azure Front Door helsesjekk feiler for Norway East
3. Verifiser:
- Trafikk rutes til APIM i Sweden Central
- APIM i Sweden Central nar Azure OpenAI i Sweden Central
- Responstid er innenfor akseptabel terskel
- Alle funksjoner (chat, RAG, agent) fungerer
4. Failback:
- Gjenopprett APIM i Norway East
- Verifiser at trafikk returnerer til primaer
Scenario L5: Komplett regional failover
Formal: Validere full DR-prosedyre med alle komponenter.
Tidsplan for full DR-drill (estimert 4-6 timer):
T+0:00 - Annonsering: "DR-drill starter"
T+0:05 - Simulert utfall av Norway East (DNS/nettverk)
T+0:10 - Deteksjon: Varsling utloeses automatisk
T+0:15 - Vurdering: Driftsteam bekrefter utfall
T+0:20 - Beslutning: Iverksett DR-plan
T+0:25 - Gateway failover: APIM rutes til Sweden Central
T+0:30 - Data failover: Verifiser Cosmos DB og Storage
T+0:45 - Agent redeploy: Deploy agentdefinisjoner i sekundaer region
T+1:00 - Validering: Funksjonelle tester
T+1:30 - Stabilisering: Overvak i 30 minutter
T+2:00 - Normal drift fra sekundaer region bekreftet
T+3:00 - Failback paabegynnes
T+3:30 - Primaer region gjenopprettet
T+4:00 - Normal drift fra primaer region bekreftet
T+4:30 - Retrospektiv og dokumentasjon
Validering og overvaking under failover
Helsesjekk-endepunkter
Implementer dedikerte helsesjekk-endepunkter for AI-tjenestene:
# health_check.py -- Eksempel pa helsesjekk for AI-stack
import asyncio
from datetime import datetime
from openai import AzureOpenAI
async def check_openai_health(endpoint: str, api_key: str) -> dict:
"""Sjekk Azure OpenAI tilgjengelighet og latens."""
start = datetime.now()
try:
client = AzureOpenAI(
azure_endpoint=endpoint,
api_key=api_key,
api_version="2024-06-01"
)
response = client.chat.completions.create(
model="gpt-4o",
messages=[{"role": "user", "content": "ping"}],
max_tokens=5,
temperature=0
)
latency_ms = (datetime.now() - start).total_seconds() * 1000
return {
"status": "healthy",
"latency_ms": round(latency_ms),
"endpoint": endpoint,
"model": "gpt-4o",
"timestamp": datetime.now().isoformat()
}
except Exception as e:
return {
"status": "unhealthy",
"error": str(e),
"endpoint": endpoint,
"timestamp": datetime.now().isoformat()
}
async def check_cosmos_health(endpoint: str) -> dict:
"""Sjekk Cosmos DB tilgjengelighet."""
# Implementer med Azure Cosmos DB SDK
pass
async def full_health_check() -> dict:
"""Komplett helsesjekk for alle AI-komponenter."""
results = await asyncio.gather(
check_openai_health("https://svv-aoai-ne.openai.azure.com", "***"),
check_openai_health("https://svv-aoai-sc.openai.azure.com", "***"),
check_cosmos_health("https://svv-ai-cosmos.documents.azure.com"),
)
overall = "healthy" if all(r["status"] == "healthy" for r in results) else "degraded"
return {"overall": overall, "components": results}
KQL-queries for failover-overvaking
// Overvaak feilrate under failover-test
AppRequests
| where TimeGenerated > ago(1h)
| where AppRoleName == "ai-gateway"
| summarize
TotalRequests = count(),
FailedRequests = countif(ResultCode >= 500),
AvgDuration = avg(DurationMs),
P95Duration = percentile(DurationMs, 95),
P99Duration = percentile(DurationMs, 99)
by bin(TimeGenerated, 1m)
| extend FailureRate = round(todouble(FailedRequests) / TotalRequests * 100, 2)
| order by TimeGenerated desc
// Sporr backend-skifte under failover
AppDependencies
| where TimeGenerated > ago(1h)
| where DependencyType == "HTTP"
| where Target contains "openai.azure.com"
| summarize
RequestCount = count(),
AvgDuration = avg(DurationMs),
FailCount = countif(ResultCode >= 400)
by bin(TimeGenerated, 1m), Target
| order by TimeGenerated desc
// Cosmos DB failover-hendelser
AzureDiagnostics
| where ResourceProvider == "MICROSOFT.DOCUMENTDB"
| where Category == "DataPlaneRequests"
| where TimeGenerated > ago(1h)
| summarize
RequestCount = count(),
AvgLatency = avg(duration_s * 1000),
ErrorCount = countif(statusCode_s >= "400")
by bin(TimeGenerated, 1m), regionName_s
| order by TimeGenerated desc
Azure Monitor Dashboard for failover
Opprett et dedikert dashboard for failover-overvaking:
| Panel | Metrikk | Terskel (groen) | Terskel (roed) |
|---|---|---|---|
| AOAI feilrate | % 4xx/5xx | < 1% | > 5% |
| AOAI latens (P95) | Millisekunder | < 2000 ms | > 5000 ms |
| APIM throughput | Requests/min | > 80% av baseline | < 50% av baseline |
| Cosmos DB latens | Millisekunder | < 50 ms | > 200 ms |
| Cosmos DB tilgjengelighet | % | > 99.9% | < 99% |
| Aktiv region | Region-label | Primaer | Sekundaer |
Suksesskriterier og akseptanseterskel
Definerte suksesskriterier per testnivaa
| Testnivaa | Kriterie | Maal | Akseptabelt | Feil |
|---|---|---|---|---|
| L1: Endepunkt-failover | Gjenopprettingstid | < 10 sek | < 30 sek | > 30 sek |
| Feilrate under failover | 0% | < 2% | > 5% | |
| Latensoekning | < 50% | < 100% | > 200% | |
| L2: Cosmos DB failover | Gjenopprettingstid | < 2 min | < 5 min | > 10 min |
| Datatap (RPO) | 0 sek | < 10 sek | > 60 sek | |
| Agentfunksjonalitet | Full | Degradert | Utilgjengelig | |
| L3: Gateway-failover | Gjenopprettingstid | < 5 min | < 15 min | > 30 min |
| Feilrate for sluttbrukere | < 1% | < 5% | > 10% | |
| Funksjonell dekning | 100% | > 90% | < 80% | |
| L5: Full regional | Gjenopprettingstid (RTO) | < 30 min | < 60 min | > 120 min |
| Datatap (RPO) | < 5 min | < 30 min | > 60 min | |
| Alle tjenester operative | 100% | > 95% | < 90% |
Akseptanseprotokoll
FAILOVER-TEST AKSEPTANSEPROTOKOLL
==================================
Testdato: _______________
Testnivaa: [ ] L1 [ ] L2 [ ] L3 [ ] L4 [ ] L5 [ ] L6
Testleder: _______________
Deltakere: _______________
RESULTATER:
-----------
Malt RTO: _____ min/sek
Malt RPO: _____ min/sek
Maks feilrate: _____ %
Maks latensoekning: _____ %
Funksjoner tilgjengelig: _____ %
VURDERING:
----------
[ ] BESTATT -- Alle kriterier innenfor "Maal"
[ ] AKSEPTABELT -- Alle kriterier innenfor "Akseptabelt"
[ ] FEIL -- Ett eller flere kriterier i "Feil"-sonen
AVVIK OG MERKNADER:
____________________________________________________
____________________________________________________
SIGNATUR:
Testleder: _____________ Dato: __________
Godkjenner: ____________ Dato: __________
Baseline-maling
Foer failover-testing ma du etablere en baseline for normal ytelse:
# Kjoer baseline-lasttest med Azure Load Testing
az load test create \
--name ai-baseline-test \
--resource-group rg-ai-prod \
--location norwayeast \
--test-plan tests/baseline-load-test.jmx \
--engine-instances 2
# Baseline-kriterier (eksempel):
# - Gjennomsnittlig responstid: < 1500 ms
# - P95 responstid: < 3000 ms
# - Feilrate: < 0.5%
# - Throughput: > 50 req/sek
Dokumentasjon og laerdommer
Testreportmal
# Failover Test Report
## Testoversikt
- **Dato:** 2026-02-15
- **Scenario:** L3 -- Full gateway-failover
- **Varighet:** 2 timer 15 minutter
- **Deltakere:** [Navn og roller]
## Sammendrag
[2-3 setninger om hva som ble testet og hovedresultatet]
## Testforloep
| Tid | Hendelse | Status |
|-----|---------|--------|
| 10:00 | Test startet, normal trafikk | OK |
| 10:05 | Primaer gateway deaktivert | OK |
| 10:05:12 | Foerste feil detektert av monitor | OK |
| 10:05:45 | Trafikk rutes til sekundaer | OK |
| 10:06:30 | Alle helsesjekker gronne | OK |
| ... | ... | ... |
## Malte resultater
| Kriterie | Maal | Resultat | Status |
|---------|------|---------|--------|
| RTO | < 5 min | 1 min 30 sek | BESTATT |
| Feilrate | < 5% | 2.1% | BESTATT |
| Latens P95 | < 3000 ms | 2800 ms | BESTATT |
## Funn og observasjoner
1. [Funn 1: Beskrivelse og alvorlighet]
2. [Funn 2: Beskrivelse og alvorlighet]
## Forbedringstiltak
| # | Tiltak | Prioritet | Ansvarlig | Frist |
|---|--------|-----------|-----------|-------|
| 1 | [Tiltak] | Hoey | [Navn] | [Dato] |
| 2 | [Tiltak] | Middels | [Navn] | [Dato] |
## Laerdommer (Lessons Learned)
- **Hva fungerte bra:** [Beskrivelse]
- **Hva kan forbedres:** [Beskrivelse]
- **Uventede funn:** [Beskrivelse]
Kunnskapsbase for failover-laerdommer
Bygg en loepende kunnskapsbase med laerdommer fra failover-tester:
| Dato | Scenario | Laerdom | Tiltak | Status |
|---|---|---|---|---|
| 2026-01-15 | L1 | Circuit breaker brukte 45 sek (for lang) | Reduser timeout til 10 sek | Implementert |
| 2026-02-01 | L2 | Cosmos DB failover tok 8 min (mal: 5 min) | Aktiver service-managed failover | Planlagt |
| 2026-02-15 | L3 | DNS-propagering tok 10 min | Reduser TTL til 60 sek | Under arbeid |
Post-incident review-prosess
Etter hver failover-test (og spesielt etter reelle hendelser):
1. Samle data (innen 24 timer)
- Loggfiler fra alle komponenter
- Metrikkdata fra Azure Monitor
- Tidslinje for hendelser
- Kommunikasjonslogg
2. Gjennomfoere retrospektiv (innen 1 uke)
- Blameless post-mortem
- Identifiser rotaarsaker
- Dokumenter tidslinje
- Klassifiser funn (kritisk/hoey/middels/lav)
3. Definere tiltak (under retrospektiv)
- Konkrete tiltak med eier og frist
- Oppdater DR-plan
- Oppdater runbooks
- Planlegg oppfoelgingstest
4. Foelg opp (loepende)
- Sporr tiltak i Linear/backlog
- Verifiser implementering
- Test forbedringer i neste planlagte test
Regelmessig testplanlegging og frekvens
Anbefalt testfrekvens
| Testtype | Frekvens | Deltakere | Estimert tid |
|---|---|---|---|
| L1: Endepunkt-failover | Ukentlig (automatisert) | CI/CD pipeline | 5-10 min |
| L2: Komponent-failover | Manedlig | Driftsteam (2-3 personer) | 1-2 timer |
| L3: Gateway-failover | Kvartalsvis | Drifts- + utviklingsteam | 2-4 timer |
| L5: Full regional drill | Halvaarlig | Alle (inkl. ledelse) | 4-8 timer |
| Tabletop exercise | Kvartalsvis | Arkitektur + drift + forretning | 2 timer |
| Chaos engineering | Lopende i CI/CD | Automatisert | Varierer |
Arsplan for failover-testing
Q1 (jan-mar):
- Uke 2: Tabletop exercise (alle scenarier)
- Uke 4: L2 komponent-test (Cosmos DB failover)
- Uke 8: L3 gateway-failover
- Uke 12: L5 FULL DR-DRILL
Q2 (apr-jun):
- Uke 14: Tabletop exercise (nye scenarier)
- Uke 17: L2 komponent-test (Storage failover)
- Uke 20: L3 gateway-failover
- Uke 24: L2 komponent-test (AI Search recovery)
Q3 (jul-sep):
- Uke 27: Tabletop exercise (oppdatert DR-plan)
- Uke 30: L2 komponent-test (Cosmos DB failover)
- Uke 33: L3 gateway-failover
- Uke 36: L5 FULL DR-DRILL
Q4 (okt-des):
- Uke 40: Tabletop exercise (arsrevisjon)
- Uke 43: L2 komponent-test (valgfritt scenario)
- Uke 46: L3 gateway-failover
- Uke 50: Arlig DR-rapportering og planrevisjon
Automatisert failover-testing i CI/CD
Integrer L1-tester i CI/CD-pipeline:
# azure-pipelines.yml -- Failover test stage
- stage: FailoverTest
displayName: 'Automated Failover Validation'
dependsOn: DeployStaging
condition: and(succeeded(), eq(variables['Build.SourceBranch'], 'refs/heads/main'))
jobs:
- job: RunChaosExperiment
steps:
- task: AzureCLI@2
displayName: 'Start Chaos Experiment'
inputs:
azureSubscription: 'svv-ai-staging'
scriptType: 'bash'
inlineScript: |
# Start chaos experiment
az chaos experiment start \
--name ai-gateway-failover-test \
--resource-group rg-ai-staging
# Vent pa at eksperimentet fullfores
az chaos experiment show \
--name ai-gateway-failover-test \
--resource-group rg-ai-staging \
--query "status" -o tsv
- task: AzureCLI@2
displayName: 'Run Load Test During Chaos'
inputs:
azureSubscription: 'svv-ai-staging'
scriptType: 'bash'
inlineScript: |
# Kjoer lasttest parallelt med chaos experiment
az load test run create \
--test-id ai-failover-load-test \
--resource-group rg-ai-staging \
--load-test-resource svv-ai-load-test
- task: AzureCLI@2
displayName: 'Validate Results'
inputs:
azureSubscription: 'svv-ai-staging'
scriptType: 'bash'
inlineScript: |
# Valider at feilrate er innenfor terskel
ERROR_RATE=$(az monitor metrics list \
--resource "/subscriptions/{sub}/..." \
--metric "FailedRequests" \
--interval PT1M \
--query "value[0].timeseries[0].data[-1].total" -o tsv)
if [ "$ERROR_RATE" -gt "5" ]; then
echo "##vso[task.logissue type=error]Failover test failed: error rate $ERROR_RATE% exceeds 5% threshold"
exit 1
fi
echo "Failover test passed: error rate $ERROR_RATE%"
Azure Chaos Studio + Azure Load Testing-integrasjon
Microsoft anbefaler a kombinere Chaos Studio (feilinjeksjon) med Azure Load Testing (syntetisk last) for realistisk failover-validering:
+------------------+ +---------------------+
| Azure Load | | Azure Chaos Studio |
| Testing | | |
| (syntetisk last) | | (feilinjeksjon) |
+--------+---------+ +---------+-----------+
| |
| Parallelkjoering |
+------------+------------+
|
+-------v--------+
| AI Application |
| (staging) |
+-------+--------+
|
+------------+------------+
| |
+--------v---------+ +--------v---------+
| Azure OpenAI | | Azure OpenAI |
| (Norway East) | | (Sweden Central) |
+------------------+ +------------------+
Viktig: Under kombinert chaos + load testing vil man forvente hoeyere feilrate og latens enn normalt. Definer separate baseline-verdier for "normal" og "chaos"-tilstand.
Referanser
- What is Azure Chaos Studio?
- Create a chaos experiment - Cosmos DB failover
- Continuous validation with Azure Load Testing and Chaos Studio
- Architecture strategies for designing a reliability testing strategy
- Architecture strategies for disaster recovery
- Shift right to test in production - Fault injection
- Deployment and testing for mission-critical workloads on Azure
For Cosmo
- Bruk denne referansen nar kunden har implementert DR-infrastruktur men mangler en testplan -- en DR-loesning uten testing er like risikabel som ingen DR-loesning.
- Start med L1-tester (automatisert) for a bygge erfaring og tillit foer man gradvis oeker til L3 og L5 -- dette reduserer risikoen for at tester selv forarsaker utfall.
- Anbefal Azure Chaos Studio + Azure Load Testing-kombinasjonen som standard verktoeysett. Chaos Studio er GA og stoetter service-direct faults mot Cosmos DB, som er den mest kritiske AI-komponenten a teste.
- Fremhev at failover-testing ma inkludere hele AI-stakken -- ikke bare inferens-endepunktet. Samtalehistorikk (Cosmos DB), kunnskapsbaser (AI Search), og agent-definisjoner ma alle valideres under failover.
- Bruk akseptanseprotokollen og rapportmalen for a gi kunden konkrete verktøy de kan ta i bruk umiddelbart. Dokumentasjon av tester er like viktig som selve testingen for kontinuerlig forbedring.