[For IT Pros]

Cloud bills in 2026 have a habit of creeping up quietly, then suddenly becoming someone’s emergency. If you own Azure in your org, you’re now expected to be part architect, part accountant, and part negotiator. This guide is the practical cost optimisation playbook I wish every IT team had from day one.

I’ll focus on things you can actually implement this week: concrete Azure Portal paths, CLI examples, governance patterns, and a simple way to get finance, security, and engineering aligned around cost.

1. Get Visibility First: Build a Cost Baseline That Actually Means Something

1.1 Stop Looking at the Total, Start Looking at Owners

Your first job is to move from “we spend £X on Azure” to “Team A spends £Y on these services for this reason.” Without ownership, every optimisation conversation turns into politics.

Minimum viable structure (if you don’t already have one):

  • Management Groups: One per major business area (e.g. mg-Production, mg-NonProd, mg-Sandbox).
  • Subscriptions: Split by environment and/or system, but always with a cost owner (e.g. sub-App1-Prod, sub-DataPlatform-NonProd).
  • Tags: Make these mandatory via policy: CostCenter, Owner, Environment, Application.

Example: Azure Policy to require core tags (assign at Management Group level):

{
  "properties": {
    "displayName": "Require cost tags on resources",
    "policyType": "Custom",
    "mode": "Indexed",
    "parameters": {},
    "policyRule": {
      "if": {
        "field": "type",
        "notEquals": "Microsoft.Resources/subscriptions/resourceGroups"
      },
      "then": {
        "effect": "deny",
        "details": {
          "type": "Microsoft.Resources/tags",
          "existenceCondition": {
            "allOf": [
              {"field": "tags['CostCenter']", "exists": "true"},
              {"field": "tags['Owner']", "exists": "true"},
              {"field": "tags['Environment']", "exists": "true"},
              {"field": "tags['Application']", "exists": "true"}
            ]
          }
        }
      }
    }
  }
}

1.2 Use the Right Tools in 2026: Cost Management + Exports + FinOps Dashboards

Step-by-step: create an actionable view in Azure Cost Management

  • In the Azure Portal: Cost Management & Billing > Cost Management > Cost analysis.
  • Set Scope to a Management Group (not just a subscription).
  • Group by: Tag:CostCenter or Tag:Owner.
  • Filter: Last 30 days, then set the granularity to Monthly for trend.
  • Save as a custom view: e.g. Cost by Team – Last 30 days.

For deeper analysis, enable cost exports to a storage account and connect to Power BI or your FinOps tooling.

CLI to create a cost export (daily):

az costmanagement export create \
  --name daily-export \
  --type Usage \
  --scope "/subscriptions/<subscription-id>" \
  --storage-account-id "/subscriptions/<subscription-id>/resourceGroups/rg-cost-data/providers/Microsoft.Storage/storageAccounts/stcostdata" \
  --timeframe MonthToDate \
  --recurrence Daily \
  --recurrence-period "start=2026-01-01T00:00:00Z end=2026-12-31T00:00:00Z"

Outcome: A daily CSV in Blob Storage that you can wire into an internal FinOps dashboard, plus historical trends that survive RBAC changes or portal view issues.

2. Attack the Big Three: Compute, Storage, and Data Egress

2.1 Compute: Rightsize, Schedule, and Commit

In most orgs I see, 60–75% of the Azure bill is some form of compute. Start here.

2.1.1 Rightsizing VMs and App Services

Where to look:

  • Azure Advisor > Cost – filter for “Right-size or shutdown underutilized virtual machines”.
  • Monitor > Metrics – CPU, memory (Guest OS metrics or Azure Monitor Agent), and disk IOPS over 30 days.

Example rule of thumb: If a production VM spends >70% of its life under 20% CPU and memory, downsize one tier and re‑check in a week.

Sample PowerShell to fetch VM utilisation (if you’ve enabled guest metrics):

$subscriptionId = "<sub-id>"
Select-AzSubscription -SubscriptionId $subscriptionId

$vmList = Get-AzVM

foreach ($vm in $vmList) {
  $metrics = Get-AzMetric -ResourceId $vm.Id `
    -MetricName "Percentage CPU" `
    -TimeGrain 1.00:00:00 `
    -StartTime (Get-Date).AddDays(-30) `
    -EndTime (Get-Date)

  $avgCpu = [math]::Round(($metrics.Data.Average | Measure-Object -Average).Average,2)
  [PSCustomObject]@{
    Name     = $vm.Name
    Size     = $vm.HardwareProfile.VmSize
    AvgCPU30 = "$avgCpu%"
  }
}

2.1.2 Schedule Non‑Prod to Sleep

Non‑prod environments left on 24/7 are pure waste. In most businesses you can safely shut them down ~60–70% of the time.

Quick win with Automation / Logic Apps:

  • Create a tag on non‑prod VMs: AutoShutdown = true.
  • Use an Automation Runbook or Logic App scheduled trigger to stop / start VMs based on that tag.

Example PowerShell Runbook snippet:

$rgName = "rg-nonprod"
$vms = Get-AzVM -ResourceGroupName $rgName | Where-Object { $_.Tags["AutoShutdown"] -eq "true" }

foreach ($vm in $vms) {
  Write-Output "Stopping VM $($vm.Name)"
  Stop-AzVM -Name $vm.Name -ResourceGroupName $rgName -Force
}

2.1.3 Use Savings Plans and Reservations Intelligently (2026 Reality)

As of 2026, most orgs should have a mix of Azure Savings Plans and specific Reserved Instances for very stable workloads.

  • Use Savings Plans if you have fluctuating workloads but a predictable minimum spend.
  • Use Reservations for always‑on services: core databases, core VMs, always‑hot AKS nodepools.

Process to avoid over‑committing:

  1. Pull 6–12 months of compute spend from Cost Management.
  2. Identify the “floor” – the minimum monthly compute usage that never goes away.
  3. Commit to ~60–70% of that floor with Savings Plans first.
  4. Layer reservations on top for genuinely fixed workloads.

2.2 Storage: Tiering, Lifecycle, and Redundancy Choices

Storage looks cheap until you multiply TBs by 36 months and factor in replication and snapshots. In 2026, most Azure tenants have years of forgotten blobs and managed disk snapshots.

2.2.1 Apply Lifecycle Management to Blob Storage

Scenario: Application logs kept in hot storage for three years “just in case.”

Fix: Apply a lifecycle policy that moves old data to cool/archive and then deletes it.

Example lifecycle policy JSON:

{
  "rules": [
    {
      "name": "logs-tiering",
      "enabled": true,
      "type": "Lifecycle",
      "definition": {
        "filters": {
          "blobTypes": ["blockBlob"],
          "prefixMatch": ["logs/"]
        },
        "actions": {
          "baseBlob": {
            "tierToCool": {"daysAfterModificationGreaterThan": 30},
            "tierToArchive": {"daysAfterModificationGreaterThan": 180},
            "delete": {"daysAfterModificationGreaterThan": 730}
          }
        }
      }
    }
  ]
}

Apply it under Storage Account > Data Management > Lifecycle management.

2.2.2 Right‑size Redundancy and Performance

  • Don’t use GZRS or RA‑GZRS for data that can tolerate region failure with a manual restore.
  • Standard HDD managed disks are fine for many dev/test workloads.
  • Premium SSD v2 / Ultra only where latency and IOPS actually matter – check PerfMon or App Insights first.

Quick audit using Azure Resource Graph (ARG):

Resources
| where type =~ 'microsoft.compute/disks'
| project name, sku = tostring(sku.name), location, subscriptionId
| summarize count() by sku

This gives you an instant view of how many Premium/Ultra disks you’re paying for.

2.3 Data Egress: Stop Surprise Bills at the Edge

Egress is now a serious line item, especially with multi‑cloud, SaaS integrations, and AI models pulling data out for fine‑tuning.

Key checks:

  • Move chatty services into the same region (or at least same continent) where possible.
  • Use Private Endpoints and ExpressRoute to keep traffic internal when it makes sense.
  • Avoid unnecessary cross‑region replication for data that doesn’t need it.

In Cost Management, group by Meter and search for "Data Transfer Out" to identify egress hotspots.

3. Governance and Guardrails: Make Cost Control the Default

3.1 Use Policies and Blueprints (or Landing Zone Templates) for Cost Hygiene

If you’re still letting every project spin up its own pattern, cost optimisation will always be reactive. You need a landing zone that bakes cost control in.

Governance controls worth enforcing in 2026:

  • Allowed locations – avoid unplanned regions with higher pricing.
  • Allowed SKUs – block the most expensive VM families in non‑prod.
  • Mandatory tags – as in section 1 for chargeback/showback.
  • Budget alerts – per subscription and/or per CostCenter.

Example: Azure Policy to restrict VM sizes in non‑prod:

{
  "properties": {
    "displayName": "Allowed VM SKUs in NonProd",
    "policyType": "Custom",
    "mode": "Indexed",
    "parameters": {},
    "policyRule": {
      "if": {
        "allOf": [
          {"field": "type", "equals": "Microsoft.Compute/virtualMachines"},
          {"field": "tags['Environment']", "equals": "NonProd"},
          {"not": {
            "field": "Microsoft.Compute/virtualMachines/sku.name",
            "in": ["Standard_B2s", "Standard_B4ms", "Standard_D2s_v5"]
          }}
        ]
      },
      "then": {
        "effect": "deny"
      }
    }
  }
}

3.2 Budgets and Alerts That Teams Actually Pay Attention To

Generic subscription‑level alerts that go to a shared mailbox will get ignored. Tie budgets to owners and Teams channels where people live.

Example: create a budget with email + webhook:

  1. Azure Portal > Subscription > Budgets > Add.
  2. Set amount, time period, and cost filter (e.g. Tag:CostCenter = Marketing).
  3. Create alerts at 50%, 80%, 100% and send to: cost owner email + Teams/Slack webhook.

You can also deploy budgets as ARM/Bicep so new subscriptions come with them pre‑configured.

3.3 Establish a Lightweight FinOps Rhythm

You don’t need a 30‑person FinOps team. You need a repeatable rhythm.

Suggested cadence:

  • Weekly (30 mins): Cloud ops reviews new alerts, spikes, and obvious waste (idle resources).
  • Monthly (60 mins): FinOps review with key app owners – top 10 cost drivers, top 5 optimisation opportunities.
  • Quarterly: Revisit Savings Plans, reservations, and landing zone standards.

Keep it visual: a simple Power BI or Grafana dashboard with cost by app, by team, and trend over 6–12 months reduces the friction.

4. Service‑Specific Tactics for 2026 Workloads

4.1 AKS (Kubernetes): Nodepools, Autoscaling, and Spot Nodes

AKS is powerful and easy to overspend on, especially with AI and microservices everywhere.

Practical steps:

  • Separate system and user nodepools; keep system pools small and on reliable SKUs.
  • Use cluster autoscaler with sensible min/max nodes per pool.
  • Use spot nodepools for batchable / stateless workloads.

Example: creating an AKS spot nodepool (CLI):

az aks nodepool add \
  --resource-group rg-aks-prod \
  --cluster-name aks-prod-01 \
  --name spotpool \
  --priority Spot \
  --eviction-policy Delete \
  --spot-max-price -1 \
  --enable-cluster-autoscaler \
  --min-count 0 \
  --max-count 5 \
  --node-vm-size Standard_D4s_v5

4.2 Databases: SQL, PostgreSQL, and Cosmos DB

SQL / PostgreSQL managed:

  • Prefer serverless for spiky workloads; set sensible auto‑pause periods in non‑critical environments.
  • Review long‑term retention and PITR backups – many DBs have more retention than the business actually needs.

Cosmos DB:

  • Use autoscale for collections with unpredictable traffic rather than over‑provisioning RU/s.
  • Rationalise regions – multiregion is great, but every region adds cost.

4.3 AI / ML and GPU Workloads (New 2026 Reality)

GPU‑backed VMs, Azure OpenAI, and custom model hosting are now common cost traps.

Key controls:

  • Put all GPU workloads in dedicated subscriptions with their own strict budgets.
  • Use job‑based compute (Azure ML jobs, Batch) rather than long‑running GPU VMs where possible.
  • Set maximum tokens / rate limits and API keys per team for Azure OpenAI and similar services.

In Cost Management, set up a separate view + budget just for AI services to keep them visible.

5. One Concrete Next Step: Run a 30‑Day Azure Cost Sprint

Instead of trying to “fix cost” forever, run a focused 30‑day sprint with a clear goal: reduce monthly Azure spend by 15–25% without impacting SLAs.

Suggested 30‑day plan:

  • Week 1 – Visibility: Implement tagging policies, create cost views by owner, and set budgets + alerts.
  • Week 2 – Low‑Risk Wins: Turn off unused resources, implement non‑prod schedules, enable lifecycle policies on obvious blob containers.
  • Week 3 – Rightsizing: Use Advisor + metrics to downsize VMs and databases where safe; adjust AKS nodepools.
  • Week 4 – Commit & Govern: Purchase/adjust Savings Plans, lock in policies (allowed SKUs, locations), and document your landing zone cost standards.

If you do nothing else, set up proper ownership (tags), basic policies, and non‑prod scheduling. Those three alone usually pay for the time you spend reading this, several times over.