Steg 9 (R4): unified migrate-corpus.mjs --write over engineering/governance/ infrastructure/security. 327 filer mutert, verified=null, prosa byte-identisk (fra første ## seksjon), advisor urørt (0 endringer). To applier-fixes oppdaget under kjøring (TDD, RED→GREEN): - insertHeaderFields: anker faller nå tilbake når en meta-linje selv passerer 500B (2 filer pakket et avsnitt i **Status:** → Type/Source landet utenfor scan-vinduet, applierens post-write-assertion fanget + restaurerte). - normalizeStaleVerified: fjerner nå ALLE stale non-date **Verified:** i 500B-vinduet, inkl. stray body-dup rett under --- (9 mlops-genaiops-filer var ellers falskt "verified"/fresh, droppet fra worklist). Operatør-godkjent utvidelse av carve-out; kun stray metadata-linjer, aldri prosa. test-transform-criterion: precondition oppdatert til post-migrasjons-sannhet (fila bærer nå Source). Suite 728/728 grønn.
348 lines
14 KiB
Markdown
348 lines
14 KiB
Markdown
# Cost Analysis and Optimization for DR Configurations
|
||
|
||
**Last updated:** 2026-04
|
||
**Status:** GA
|
||
**Category:** Business Continuity & Disaster Recovery
|
||
**Type:** reference
|
||
**Source:** https://learn.microsoft.com/azure/cost-management-billing/cost-management-billing-overview
|
||
|
||
---
|
||
|
||
## Innhold
|
||
|
||
- [Introduksjon](#introduksjon)
|
||
- [Total Cost of Ownership-beregning](#total-cost-of-ownership-beregning)
|
||
- [RTO/RPO vs. kostnads trade-off analyse](#rtorpo-vs-kostnads-trade-off-analyse)
|
||
- [Reserved Capacity vs. On-Demand prising](#reserved-capacity-vs-on-demand-prising)
|
||
- [Cross-region bandwidth-kostnader](#cross-region-bandwidth-kostnader)
|
||
- [Kostnadsoptimalisering og Reserved Instances](#kostnadsoptimalisering-og-reserved-instances)
|
||
- [Referanser](#referanser)
|
||
- [For Cosmo](#for-cosmo)
|
||
|
||
## Introduksjon
|
||
|
||
Kostnadsanalyse av BCDR-løsninger for AI-systemer er avgjørende for å sikre at organisasjonen investerer riktig i resiliens. DR-kostnader kan utgjøre alt fra 2% til 100% av primære driftskostnader, avhengig av valgt strategi. For AI-workloads er kostnadene spesielt høye fordi tjenester som Azure OpenAI (Provisioned Throughput), AI Search og GPU-compute er dyre.
|
||
|
||
Azure Well-Architected Framework anbefaler at DR-kostnad skal stå i proporsjonal sammenheng med forretningsverdien av systemet og konsekvensene av nedetid. Tier 0 (Mission Critical) systemer rettferdiggjør høye DR-kostnader, mens Tier 3 (Administrative) systemer bør minimere kostnadene.
|
||
|
||
For norsk offentlig sektor krever Utredningsinstruksen at alternative løsninger evalueres med kost/nytte-analyse. BCDR-valg bør dokumenteres med tydelig kostnadssammenligning og forretningsbegrunnelse.
|
||
|
||
## Total Cost of Ownership-beregning
|
||
|
||
### TCO-modell for AI BCDR
|
||
|
||
```python
|
||
# TCO-kalkulator for AI DR-konfigurasjon
|
||
from dataclasses import dataclass
|
||
from typing import Dict
|
||
|
||
@dataclass
|
||
class AIDRCostModel:
|
||
"""Calculate Total Cost of Ownership for AI DR configuration."""
|
||
|
||
# Primær region kostnader (monthly NOK)
|
||
openai_primary_monthly: float = 0
|
||
search_primary_monthly: float = 0
|
||
cosmos_primary_monthly: float = 0
|
||
app_service_primary_monthly: float = 0
|
||
storage_primary_monthly: float = 0
|
||
networking_primary_monthly: float = 0
|
||
|
||
def calculate_dr_cost(self, strategy: str) -> Dict:
|
||
"""Calculate DR cost for given strategy."""
|
||
primary_total = sum([
|
||
self.openai_primary_monthly,
|
||
self.search_primary_monthly,
|
||
self.cosmos_primary_monthly,
|
||
self.app_service_primary_monthly,
|
||
self.storage_primary_monthly,
|
||
self.networking_primary_monthly
|
||
])
|
||
|
||
if strategy == "active-active":
|
||
dr_costs = {
|
||
"openai": self.openai_primary_monthly * 1.0,
|
||
"search": self.search_primary_monthly * 1.0,
|
||
"cosmos": self.cosmos_primary_monthly * 0.5, # Multi-region included
|
||
"app_service": self.app_service_primary_monthly * 1.0,
|
||
"storage": self.storage_primary_monthly * 0.3, # GRS overhead
|
||
"networking": self.networking_primary_monthly * 0.5, # Cross-region
|
||
"bandwidth": primary_total * 0.02 # ~2% for replication
|
||
}
|
||
|
||
elif strategy == "warm-standby":
|
||
dr_costs = {
|
||
"openai": self.openai_primary_monthly * 0.3, # Pay-per-token, lower usage
|
||
"search": self.search_primary_monthly * 0.67, # 2/3 replicas
|
||
"cosmos": self.cosmos_primary_monthly * 0.3, # Autoscale baseline
|
||
"app_service": self.app_service_primary_monthly * 0.33, # 1 instance
|
||
"storage": self.storage_primary_monthly * 0.3,
|
||
"networking": self.networking_primary_monthly * 0.2,
|
||
"bandwidth": primary_total * 0.01
|
||
}
|
||
|
||
elif strategy == "cold-standby":
|
||
dr_costs = {
|
||
"openai": 0, # Redeploy on demand
|
||
"search": 0, # Rebuild on demand
|
||
"cosmos": self.cosmos_primary_monthly * 0.1, # Backup only
|
||
"app_service": 0, # Deploy on demand
|
||
"storage": self.storage_primary_monthly * 0.3, # GRS for data
|
||
"networking": self.networking_primary_monthly * 0.05,
|
||
"bandwidth": primary_total * 0.005
|
||
}
|
||
|
||
elif strategy == "backup-restore":
|
||
dr_costs = {
|
||
"openai": 0,
|
||
"search": 0,
|
||
"cosmos": self.cosmos_primary_monthly * 0.05,
|
||
"app_service": 0,
|
||
"storage": self.storage_primary_monthly * 0.15, # Backup storage
|
||
"networking": 0,
|
||
"bandwidth": 0
|
||
}
|
||
|
||
dr_total = sum(dr_costs.values())
|
||
|
||
return {
|
||
"strategy": strategy,
|
||
"primary_monthly_nok": round(primary_total),
|
||
"dr_monthly_nok": round(dr_total),
|
||
"total_monthly_nok": round(primary_total + dr_total),
|
||
"dr_percentage": round(dr_total / primary_total * 100, 1),
|
||
"dr_annual_nok": round(dr_total * 12),
|
||
"breakdown": {k: round(v) for k, v in dr_costs.items()}
|
||
}
|
||
|
||
# Eksempel for typisk norsk offentlig AI-løsning
|
||
model = AIDRCostModel(
|
||
openai_primary_monthly=25000, # GPT-4o, ~500K tokens/dag
|
||
search_primary_monthly=15000, # Standard S1, 3 replicas
|
||
cosmos_primary_monthly=8000, # Multi-region, 10K RU/s
|
||
app_service_primary_monthly=12000, # P3v3 x 3
|
||
storage_primary_monthly=3000, # 1 TB GZRS
|
||
networking_primary_monthly=5000 # Front Door + VNet
|
||
)
|
||
|
||
for strategy in ["active-active", "warm-standby", "cold-standby", "backup-restore"]:
|
||
result = model.calculate_dr_cost(strategy)
|
||
print(f"\n{strategy.upper()}")
|
||
print(f" DR kostnad: {result['dr_monthly_nok']:,} NOK/mnd ({result['dr_percentage']}%)")
|
||
print(f" Total: {result['total_monthly_nok']:,} NOK/mnd")
|
||
print(f" Årlig DR: {result['dr_annual_nok']:,} NOK")
|
||
```
|
||
|
||
### Kostnadsoversikt per strategi
|
||
|
||
| Komponent | Primær | Active-Active | Warm Standby | Cold Standby | Backup Only |
|
||
|-----------|--------|---------------|-------------|-------------|-------------|
|
||
| Azure OpenAI | 25,000 | 25,000 | 7,500 | 0 | 0 |
|
||
| AI Search | 15,000 | 15,000 | 10,000 | 0 | 0 |
|
||
| Cosmos DB | 8,000 | 4,000 | 2,400 | 800 | 400 |
|
||
| App Service | 12,000 | 12,000 | 4,000 | 0 | 0 |
|
||
| Storage | 3,000 | 900 | 900 | 900 | 450 |
|
||
| Networking | 5,000 | 2,500 | 1,000 | 250 | 0 |
|
||
| Bandwidth | — | 1,360 | 680 | 340 | 0 |
|
||
| **DR total/mnd** | — | **60,760** | **26,480** | **2,290** | **850** |
|
||
| **% av primær** | — | **89%** | **39%** | **3%** | **1%** |
|
||
| **RTO** | — | ~0 | 5–15 min | 30–60 min | Timer |
|
||
| **RPO** | — | ~0 | Minutter | Timer | 24 timer |
|
||
|
||
*Alle beløp i NOK, estimat for typisk offentlig sektor AI-løsning.*
|
||
|
||
## RTO/RPO vs. kostnads trade-off analyse
|
||
|
||
### Beslutningsmatrise
|
||
|
||
```
|
||
Kostnad (NOK/mnd)
|
||
│
|
||
│ Active-Active
|
||
│ ■ (60K)
|
||
│
|
||
│ Warm Standby
|
||
│ ■ (26K)
|
||
│
|
||
│
|
||
│
|
||
│ Cold Standby
|
||
│ ■ (2.3K)
|
||
│ Backup/Restore
|
||
│ ■ (850)
|
||
└─────────────────────────────────────────────────── RTO
|
||
0 5min 15min 30min 1h 4h 24h
|
||
```
|
||
|
||
### Break-even analyse
|
||
|
||
```markdown
|
||
## Når er Active-Active verdt det?
|
||
|
||
Merkostnad Active-Active vs. Warm Standby:
|
||
60,760 - 26,480 = 34,280 NOK/mnd = 411,360 NOK/år
|
||
|
||
For at Active-Active skal være verdt det, må kostnaden
|
||
av nedetid overstige denne merkostnaden:
|
||
|
||
Nedetid-kostnad per hendelse = (RTO_warm - RTO_active) × Kostnad per minutt
|
||
Forventet besparelse = Nedetid-kostnad × Antall hendelser per år
|
||
|
||
Eksempel:
|
||
- RTO forskjell: 15 min vs. ~0 = 15 min
|
||
- Kostnad per minutt nedetid: 5,000 NOK (tapt produktivitet, omdømme)
|
||
- Antall hendelser per år: 2
|
||
|
||
Besparelse = 15 min × 5,000 NOK × 2 = 150,000 NOK/år
|
||
|
||
Merkostnad 411,360 > Besparelse 150,000 → Warm Standby er bedre valg
|
||
|
||
Break-even: 411,360 / (15 × 5,000) = 5.5 hendelser/år
|
||
→ Trenger 6+ hendelser/år for at Active-Active lønner seg
|
||
```
|
||
|
||
## Reserved Capacity vs. On-Demand prising
|
||
|
||
### Besparelser med Reserved Instances
|
||
|
||
| Tjeneste | On-Demand/mnd | 1-år RI/mnd | 3-år RI/mnd | Besparelse 1-år | Besparelse 3-år |
|
||
|----------|-------------|-------------|-------------|----------------|----------------|
|
||
| App Service P3v3 | 12,000 | 7,800 | 5,400 | 35% | 55% |
|
||
| AI Search S1 (3 rep) | 15,000 | 9,750 | 6,750 | 35% | 55% |
|
||
| Azure OpenAI PTU (50) | 50,000 | 35,000 | — | 30% | — |
|
||
| Redis Premium P1 | 4,500 | 3,150 | 2,250 | 30% | 50% |
|
||
|
||
### RI-strategi for DR
|
||
|
||
```markdown
|
||
## Anbefalte reservasjoner for DR
|
||
|
||
### Active-Active DR
|
||
- RI for ALLE tjenester i begge regioner (full besparelse)
|
||
- Anbefaling: 1-år RI minimum, 3-år for stabile workloads
|
||
|
||
### Warm Standby DR
|
||
- RI for baseline-kapasitet i DR-region (lavere tier)
|
||
- On-demand for burst/scale-up kapasitet
|
||
- Anbefaling: 1-år RI for baseline, on-demand for topper
|
||
|
||
### Cold Standby DR
|
||
- INGEN RI for DR-region (ressurser kjører ikke)
|
||
- RI kun for primær region
|
||
- Anbefaling: Bruk Azure Savings Plans for fleksibilitet
|
||
|
||
### Savings Plans alternativ
|
||
Azure Savings Plans gir 1-år eller 3-år commitment
|
||
med fleksibilitet til å bruke kapasiteten i hvilken som helst
|
||
region — ideelt for DR der regionen kan endres.
|
||
```
|
||
|
||
## Cross-region bandwidth-kostnader
|
||
|
||
### Bandwidth-prising mellom Azure-regioner
|
||
|
||
| Datatype | Volume/mnd | Pris/GB | Kostnad/mnd |
|
||
|----------|-----------|---------|-------------|
|
||
| Cosmos DB replikering | 50 GB | Inkludert | 0 |
|
||
| Blob Storage GRS | 100 GB | ~0.70 NOK | 70 |
|
||
| AI Search index sync | 10 GB | ~0.70 NOK | 7 |
|
||
| Application data | 200 GB | ~0.70 NOK | 140 |
|
||
| **Total bandwidth** | **360 GB** | — | **~217 NOK** |
|
||
|
||
*Intra-Europa bandwidth er relativt rimelig. Kostnaden øker betydelig for cross-kontinent replikering.*
|
||
|
||
### Optimalisering av bandwidth-kostnader
|
||
|
||
```markdown
|
||
## Bandwidth-optimaliseringsstrategier
|
||
|
||
1. **Komprimering**: Aktiver gzip/brotli for all cross-region trafikk
|
||
- Typisk besparelse: 60–80% på tekstbasert data
|
||
|
||
2. **Delta-replikering**: Synkroniser kun endringer, ikke full kopi
|
||
- Bruk Azure Blob Storage Change Feed
|
||
- Event-driven sync i stedet for full re-indeksering
|
||
|
||
3. **Batch vs. real-time**: Batchvise oppdateringer reduserer overhead
|
||
- Samle opp endringer og synkroniser hvert 5. minutt
|
||
|
||
4. **CDN for statisk innhold**: Bruk Azure CDN for dokumenter
|
||
- Reduserer cross-region trafikk for hyppig leste filer
|
||
```
|
||
|
||
## Kostnadsoptimalisering og Reserved Instances
|
||
|
||
### Azure Cost Management dashboard
|
||
|
||
```bash
|
||
# Opprett kostnadsrapport for DR-ressurser
|
||
az costmanagement export create \
|
||
--name "dr-cost-report" \
|
||
--scope "/subscriptions/{sub}/resourceGroups/rg-ai-dr" \
|
||
--type "ActualCost" \
|
||
--timeframe "MonthToDate" \
|
||
--storage-account "stacostmgmt" \
|
||
--storage-container "cost-reports" \
|
||
--recurrence "Monthly" \
|
||
--recurrence-period '{"from": "2026-01-01", "to": "2026-12-31"}'
|
||
|
||
# Sett budsjett med varsler
|
||
az consumption budget create \
|
||
--budget-name "ai-dr-budget-2026" \
|
||
--amount 400000 \
|
||
--category "Cost" \
|
||
--time-grain "Annually" \
|
||
--time-period '{"Start": "2026-01-01", "End": "2026-12-31"}' \
|
||
--resource-groups "rg-ai-dr" \
|
||
--notifications '{
|
||
"Warning50": {"enabled": true, "operator": "GreaterThan", "threshold": 50,
|
||
"contactEmails": ["platform@org.no"]},
|
||
"Warning80": {"enabled": true, "operator": "GreaterThan", "threshold": 80,
|
||
"contactEmails": ["platform@org.no", "management@org.no"]},
|
||
"Critical100": {"enabled": true, "operator": "GreaterThan", "threshold": 100,
|
||
"contactEmails": ["platform@org.no", "management@org.no", "cto@org.no"]}
|
||
}'
|
||
```
|
||
|
||
### Kvartalsvis kostnadsrapport-mal
|
||
|
||
```markdown
|
||
## BCDR Kostnadsrapport — Q[X] 2026
|
||
|
||
### Oppsummering
|
||
| Kategori | Budsjett | Faktisk | Avvik |
|
||
|----------|---------|--------|-------|
|
||
| DR infrastruktur | X NOK | X NOK | X% |
|
||
| Bandwidth | X NOK | X NOK | X% |
|
||
| DR-testing | X NOK | X NOK | X% |
|
||
| **Total** | **X NOK** | **X NOK** | **X%** |
|
||
|
||
### DR-hendelser dette kvartalet
|
||
- Antall failover-initieringer: X
|
||
- Gjennomsnittlig RTO oppnådd: X min
|
||
- Estimert verdi av DR (unngått nedetid): X NOK
|
||
|
||
### Optimaliseringsmuligheter
|
||
1. [Identifisert mulighet med estimert besparelse]
|
||
2. [...]
|
||
|
||
### Anbefalinger
|
||
- [Anbefalte endringer med kostnadspåvirkning]
|
||
```
|
||
|
||
## Referanser
|
||
|
||
- [Optimize your recovery costs](https://learn.microsoft.com/en-us/azure/well-architected/design-guides/disaster-recovery#optimize-your-recovery-costs) — WAF kostnadsoptimalisering for DR
|
||
- [Azure Site Recovery pricing](https://azure.microsoft.com/pricing/details/site-recovery/) — Prising for Site Recovery
|
||
- [Azure bandwidth pricing](https://azure.microsoft.com/pricing/details/bandwidth/) — Bandwidth-priser mellom regioner
|
||
- [Azure pricing calculator](https://azure.microsoft.com/pricing/calculator/) — Generell priskalkulator
|
||
- [Microsoft Cost Management](https://learn.microsoft.com/en-us/azure/cost-management-billing/cost-management-billing-overview) — Kostnadsovervåking. Verified (MCP 2026-04).
|
||
- [Azure Savings Plans](https://azure.microsoft.com/pricing/purchase-options/azure-saving-plans/) — Flexible reservasjoner (compute savings plans). Verified (MCP 2026-04).
|
||
|
||
## For Cosmo
|
||
|
||
- **Bruk denne referansen** når kunden trenger kostnadsestimat for BCDR-løsninger, eller når de skal sammenligne DR-strategier.
|
||
- Warm standby er sweet spot for de fleste offentlige AI-løsninger — 25–40% merkostnad for minutter RTO.
|
||
- Vis alltid break-even analyse: sammenlign DR-merkostnaden med estimert kostnad ved nedetid for å rettferdiggjøre investeringen. Verified (MCP 2026-04).
|
||
- Azure OpenAI: Pay-per-token i DR-region er nesten alltid bedre enn PTU fordi DR-trafikken er lav under normal drift.
|
||
- For Utredningsinstruksen: Presenter alltid minimum 3 alternativer (f.eks. cold/warm/active-active) med kost/nytte-vurdering.
|