Cost Management - Azure RI vs. Saving Plans
Immer wieder gibt es die Diskussion sind die Azure Reserved Instances (RI) oder der Azure Saving Plan (SP) die bessere Option für den Betrieb einer Applikation auf Basis von IaaS in Azure. Es gibt nicht die eine Antwort auf diese Frage. Im folgenden werden die beiden Optionen Reserved Instance und Saving Plan gegen übergestellt und anhand von Szenarien bewertet.
Kurze Begriffsklärung:
Azure Reserved Instance
Bei einer Reserved Instance handelt es sich im ein Commitment für einer Bestimmte VM in einer bestimmten Region für eine bestimmte Zeit. Also z.B. eine D8s_v5 VM in Westeuropa für drei Jahre. Diese Reservierung kann dann monatlich über 3 Jahre gezahlt werden und bietet ein Rabat von bis zu 72%. In diesem konkreten Beispiel liegt der Preisvorteil bei ~62% Rabatt. Wichtig dabei ist, die Reservierung muss bezahlt werden, egal ob Sie genutzt wird oder nicht. Auf MS Learn findet mal unter folgendem Link eine detaillierte Dokumentation zu dem Thema: Kostensparen mit reservierten Azure-VM-Instanzen
Azure Saving Plan
Bei einem Savin Plan wird im Gegensatz zu einer Reserved Instance nicht eine konkrete VM in einer konkreten Region reserviert, sondern nur eine Summe EUR an Compute. Dies kann dann flexibel für unterschiedliche VMs oder auch andere Compute Services genutzt werden. Die reservierte Summe wird dann monatlich abgerechnet, egal ob Sie vollständig genutzt wurde oder nicht. Sollte man mehr verbrauchen, als man committet hat, wird zum Pay-as-you-go Preis abgerechnet. Zu den Saving Plans ist die Dokumentation an folgender Stelle: Was sind Azure-Sparpläne für Compute?
Szenarios
Um eine mögliche gute Vergleichbarkeit zu bekommen, gehen wir von folgenden Szenarien aus und bewerten die Kosten der jeweiligen Lösung. Stellen wir uns vor wir haben ein Zeiterfassungssystem. Dieses System wird primär in den Zeiten zwischen 6:00 Uhr und 18:00 Uhr benötigt.
- Szenario A: Der Workload läuft 12 Stunden am Tag und könnte theoretisch komplett abgeschaltet werden in den anderen 12 Stunden
- Szenario B: Der Workload läuft 12 Stunden am Tag, muss aber in den anderen 12 Stunden weiterhin verfügbar sein, gern aber mit weniger Leistung.
- Szenario C: Der Workload läuft nur 21 Werktage 12 Stunden und könnte in der restlichen Zeit durch eine leistungsschwächere VM ersetzt werden.
Annahme | Wert | Einheit |
---|---|---|
Kalkulatorische Stunden pro Monat | 730 | Stunden |
30 Tage 6:00 - 18:00 Uhr | 360 | Stunden |
21 Arbeitstage 6:00 - 18:00 Uhr | 252 | Stunden |
Als Basis für die VM-Preise wurden die Daten aus dem Azure Preiskalkulator genommen (Region “westeurope”):
VM Type | Pay-as-you-go (PAYG) | RI | SP |
---|---|---|---|
D8s_v5 | 0,438 EUR/h | 0,166 EUR/h | 0,240 EUR/h |
D4s_v5 | 0,213 EUR/h | 0,083 EUR/h | 0,0120 EUR/h |
B4s_v2 | 0,183 EUR/h | 0,069 EUR/h | 0,097 EUR/h |
Alle Preise sind nur der Compute-Preis, also ohne Betriebssystemkosten. Preisrechner vom 10/05/2023.
Szenario A
Wenn das Zeiterfassungssystem wirklich komplett ausgeschaltet werden könnte in den Zeiten, wo es nicht genutzt wird, ergeben sich folgende Preise in einem Monat für die VM:
Konstellation | Preis |
---|---|
VM D8s_v5 als RI | 121,18 EUR/Monat |
VM D8s_v5 30 Tage 12 Stunden/Tag (PAYG) | 157,68 EUR/Monat |
VM D8s_v5 21 Tage 12 Stunden/Tag (PAYG) | 110,38 EUR/Monat |
Damit wird klar, dass es sich nur dann lohnen würde, den Pay-as-you-go Preis zu nehmen, wenn wir in den Bereich von 21 Tagen 12h am Tag kommen. Der RI-Rabatt von 62% auf den Pay-as-you-go Preis der VM zahlt sich ab ~350 Stunden Betriebszeit der VM aus.
Szenario B
Der Workload läuft 12 Stunden am Tag, muss aber in den anderen 12 Stunden weiterhin verfügbar sein, gern aber mit weniger Leistung.
Wenn alles im PAYG-Preis abgebildet wird und 12 Stunde eine D8s_v5 und 12 Stunden eine D4s_v5 genutzt werden:
VM-Größe | Preis |
---|---|
D8s_v5 | 157,68 EUR/Monat |
D4s_v5 | 81,03 EUR/Monat |
Summe Workload | 238,71 EUR/Monat |
Differenz zur RI | + 97% |
Wenn alle Preise über einen Saving Plan abgedeckt werden:
VM-Größe | Preis |
---|---|
D8s_v5 | 86,40 EUR/Monat |
D4s_v5 | 44,40 EUR/Monat |
Summe Workload | 130,80 EUR/Monat |
Differenz zur RI | + 8% |
Wenn alle Preise über einen Saving Plan abgedeckt werden und als Downsizing VM kann eine B-Series verwendet werden:
VM Größe | Preis |
---|---|
D8s_v5 | 86,40 EUR/Monat |
B4s_v2 | 35,89 EUR/Monat |
Summe Workload | 122,29 EUR/Monat |
Differenz zur RI | + 0,92% |
Damit sind wir schon fast auf dem Preis einer RI.
Szenario C
Der Workload läuft nur 21 Werktage 12 Stunden und könnte in der restlichen Zeit durch eine leistungsschwächere VM ersetzt werden.
Wenn alles im PAYG-Preis abgebildet wird und 21 Arbeitstage für 12 Stunde eine D8s_v5 genutzt wird. In den restlichen Stunden wird dann auf eine D4s_v5 verändert:
VM-Größe | Preis |
---|---|
D8s_v5 | 110,37 EUR/Monat |
D4s_v5 | 104,68 EUR/Monat |
Summe Workload | 215,05 EUR/Monat |
Differenz zur RI | + 77% |
Wenn alle Preise über einen Saving Plan abgedeckt werden:
VM-Größe | Preis |
---|---|
D8s_v5 | 60,48 EUR/Monat |
D4s_v5 | 57,36 EUR/Monat |
Summe Workload | 117,84 EUR/Monat |
Differenz zur RI | - 2,8% |
Dann noch erweitert um eine B-Serie VM anstatt der D4s_v5 im Saving Plan:
VM-Größe | Preis |
---|---|
D8s_v5 | 60,48 EUR/Monat |
B4s_v2 | 46,37 EUR/Monat |
Summe Workload | 106,85 EUR/Monat |
Differenz zur RI | - 11,8% |
Die letzten beiden Konstellationen erzeugen eine Ersparnis gegenüber der reinen RI für eine VM Größe.
Wenn man die Betrachtung nicht nur mit dem reinen Compute macht, sondern auch die Windows Lizenzen mit einkalkuliert verändert sich das Bild deutlich. Dann wird schon PAYG 30 Tage 12 Stunden in Benutzung ansonsten aus mit der gleichen VM-Größe günstiger als eine RI der gleichen VM Größe.
Konstellation | Hochrechnung |
---|---|
RI D8s_v5 | 376,68 EUR/Monat |
PAYG 30 Tage 12 Stunden | 291,56 EUR/Monat |
PAYG 21 Tage 12 Stunden | 198,58 EUR/Monat |
Inkl. Betriebssystem und ausgeschaltet, wenn nicht benötigt.
Konstellation | Szenario B | Szenario C |
---|---|---|
D8s_v5 + D4s_v5 PAYG | 429,46 EUR/Monat | 386,91 EUR/Monat |
D8s_v5 + D4s_v5 SP | 321,55 EUR/Monat | 289,69 EUR/Monat |
D8s_v5 + B4s_v2 SP | 253,84 EUR/Monat | 202,22 EUR/Monat |
In der Spitze erreicht man eine Ersparnis von über 46% gegenüber der Rerserved Instance. Hier spielt der Vorteil im Preis für das OS bei einer B-Series VM die entscheidende Rolle.
Umsetzung
Um dies auch mal praktisch umzusetzen ist hier ein kurzes Beispiel der Umsetzung.
Deployment einer VM
Der bicep-Code um eine VM bereitzustellen kann hier heruntergeladen werden oder direkt hier kopiert werden:
@description('Location to deploy the vNet and the VM')
param location string = 'westeurope'
@description('Name of the VM')
param vmName string = 'vm-sizingdemo01'
@description('Admin username for the VM')
param adminUsername string = 'demouser'
@description('Admin password for the VM')
@secure()
param adminPassword string = 'Pass!word123'
@description('Name of the vNet')
param vnetName string = 'vnet-sizingdemo'
@description('Name of the subnet')
param subnetName string = 'snet-sizingdemo'
@description('Name of the automation account')
param automationAccountName string = 'aa-sizingdemo'
resource vnet 'Microsoft.Network/virtualNetworks@2020-11-01' = {
name: vnetName
location: location
properties: {
addressSpace: {
addressPrefixes: [
'10.0.0.0/16'
]
}
subnets: [
{
name: subnetName
properties: {
addressPrefix: '10.0.0.0/24'
}
}
]
}
}
resource publicIp 'Microsoft.Network/publicIPAddresses@2020-11-01' = {
name: '${vmName}-pip'
location: location
properties: {
publicIPAllocationMethod: 'Dynamic'
}
}
resource nic 'Microsoft.Network/networkInterfaces@2020-11-01' = {
name: '${vmName}-nic'
location: location
properties: {
ipConfigurations: [
{
name: 'ipconfig'
properties: {
subnet: {
id: vnet.properties.subnets[0].id
}
publicIPAddress: {
id: publicIp.id
}
}
}
]
}
}
resource vm 'Microsoft.Compute/virtualMachines@2020-12-01' = {
name: vmName
location: location
dependsOn: [
nic
]
properties: {
hardwareProfile: {
vmSize: 'Standard_D8s_v5'
}
storageProfile: {
imageReference: {
publisher: 'MicrosoftWindowsServer'
offer: 'WindowsServer'
sku: '2019-Datacenter'
version: 'latest'
}
osDisk: {
name: '${vmName}-osdisk'
caching: 'ReadWrite'
createOption: 'FromImage'
diskSizeGB: 128
}
}
osProfile: {
computerName: vmName
adminUsername: adminUsername
adminPassword: adminPassword
}
networkProfile: {
networkInterfaces: [
{
id: nic.id
}
]
}
}
}
resource automationAccount 'Microsoft.Automation/automationAccounts@2022-08-08' = {
name: automationAccountName
location: location
properties: {
sku: {
name: 'Basic'
}
}
}
Die Parameter sollten nach eigenen Vorstellungen angepasst werden, insbesondere das Kennwort für den administrativen Zugang. Im Azure Portal ist dann folgendes bereitgestellt:
Automation Account
Der Automation Account braucht dann noch eine Berechtigung, um auf der Subscription oder Resourcegroup die VM in der Größe verändern zu können. Dazu ist in diesem Beispiel der Automation Account “aa-sizimgdemo” mit einer System Assigned Identity und dem entsprechendem Azure Role Assignment versehen worden (vgl. MS Learn):
Runbook erstellen und mit einem Schedule verbinden
Das Runbook auf Basis von Powershell zum Verändern der VM-Größe in diesem beschriebenen Szenario würde dann wie folgt aussehen:
# Set variables
$resourceGroup = "rg-sizingdemo"
$vm = "vm-sizingdemo01"
# Set desired VM-Sizes
$normalsize = "Standard_D8s_v5"
$smallersize = "Standard_B4s_v2"
# login to Azure
# Ensures you do not inherit an AzContext in your runbook
Disable-AzContextAutosave -Scope Process
# Connect to Azure with system-assigned managed identity
Connect-AzAccount -Identity
# check if the desired VM size is available
$availableSizes = Get-AzVMSize -ResourceGroupName $resourceGroup -VMName $vm | Select-Object -ExpandProperty Name
if($availableSizes -notcontains $normalsize) {
Write-Host "The desired normal VM size is not available."
exit 1
}
if($availableSizes -notcontains $smallersize) {
Write-Host "The desired smaller VM size is not available."
exit 1
}
# Check current Size
$updatevm = Get-AzVM -ResourceGroupName $resourceGroup -Name $vm
$actualsize = $updatevm.HardwareProfile.VmSize
Write-Host "Current Size is $actualsize"
$targetsize = ($actualsize -eq $normalsize) ? $smallersize : $normalsize
# Deallocate the VM
Stop-AzVM -ResourceGroupName $resourceGroup -Name $vm -StayProvisioned -Force
Write-Host "The VM is deallocated."
Write-Host "Target Size is $targetsize"
$updatevm.HardwareProfile.VmSize = $targetsize
# Resize the VM
Update-AzVM -ResourceGroupName $resourceGroup -VM $updatevm
Write-Host "New Size is $targetsize"
# Start the VM
Start-AzVM -ResourceGroupName $resourceGroup -Name $vm
Write-Host "The VM is started."
HINWEIS: Mitlerweile gibt es eine Extension für VisualStudio Code um sowohl das Runbook als auch den Schedule und die komplette Konfiguraiton direkt in VSCode zu machen.
Der Schedule wurde auf exemplarisch alle 12 Stunden gestellt:
{
"id": "/subscriptions/<YOURSUBSCRIPTION>/resourceGroups/rg-sizingdemo/providers/Microsoft.Automation/automationAccounts/aa-sizingdemo/schedules/Resizing",
"name": "Resizing",
"type": "Microsoft.Automation/AutomationAccounts/Schedules",
"startTime": "2023-10-06T16:00:00.000Z",
"startTimeOffsetMinutes": 120,
"expiryTime": "9999-12-31T23:59:59.999Z",
"expiryTimeOffsetMinutes": 0,
"isEnabled": true,
"nextRun": "2023-10-06T16:00:00.000Z",
"nextRunOffsetMinutes": 120,
"interval": 12,
"frequency": "Hour",
"timeZone": "Europe/Berlin",
"advancedSchedule": null,
"creationTime": "2023-10-06T08:45:43.643Z",
"lastModifiedTime": "2023-10-06T08:45:43.643Z",
"description": ""
}
HINWEIS: Es handelt sich nur um eine exemplarische Umsetzung. Für den produktiven Betireb empfielt sich eine Lösung, die das Resizing z.B. anhand von Tags automatisiert die VMs in der Größe anpasst, damit nicht für jede VM ein Script aufgesetzt werden muss. Beispiele dafür finden sich in der Runbook Gallery direkt im Azure Portal aufrufbar oder auf Github. Siehe auch aka.ms/AzureAutomationGitHub