Cost-Effective Azure & M365: A Practical Guide to Trimming Cloud Spend in 2026

[For IT Pros]

Cloud bills rarely explode overnight. They creep up month after month until someone in finance forwards you a shocking PDF and asks, “What changed?” If that sounds familiar, this guide is for you.

I’ll walk through concrete, 2026-ready steps you can take in Azure and Microsoft 365 to reduce spend without breaking anything or killing performance. This is the playbook I wish every IT team ran twice a year.

Step 1: Get Visibility Before You Touch Anything

1.1 Build a Cost Ownership Map

If no one owns a cost, it always grows. Start by mapping who owns what.

  • Azure: Decide if you’re tagging by application, department, or environment. Then standardise tags globally.
  • M365: Decide cost centres for licences: Sales, Ops, Contractors, Shared Services, etc.

In Azure, enforce a minimum tag set at the subscription or management group level:

{
  "env": "prod|nonprod",
  "app": "<app-name>",
  "owner": "<email-upn>",
  "costCenter": "<cc-code>"
}

Use an Azure Policy initiative to deny or modify on missing tags. Example policy (snippet) to add a default cost center if missing:

{
  "mode": "All",
  "policyRule": {
    "if": {
      "field": "tags['costCenter']",
      "exists": "false"
    },
    "then": {
      "effect": "modify",
      "details": {
        "operations": [
          {
            "operation": "add",
            "field": "tags['costCenter']",
            "value": "UNASSIGNED"
          }
        ]
      }
    }
  }
}

1.2 Turn on the Right Azure Cost Tools

In 2026, you should not be using only the basic Cost Analysis blade and Excel.

  • Enable Cost Management + Billing at the tenant root and core management groups.
  • Use the “Cost by Tag” view to see top spend by env, app, and owner.
  • Enable exports to a Storage Account or Log Analytics, then query with KQL or Power BI.

Example KQL in Log Analytics to find top 10 most expensive resources in the last 30 days:

Usage
| where TimeGenerated > ago(30d)
| summarize cost = sum(PreTaxCost) by ResourceId
| top 10 by cost desc

1.3 Baseline Microsoft 365 Licence Usage

Use the Microsoft 365 Admin Center > Reports > Usage and Entra ID sign-in logs to baseline utilisation.

  • Export user list with assigned SKU, department, and last sign-in.
  • Identify users inactive for >90 days and those using only basic workloads (e.g., mail only).

PowerShell snippet using the Microsoft Graph PowerShell SDK (2026-standard) to pull last sign-in date and licences:

Connect-MgGraph -Scopes "User.Read.All","AuditLog.Read.All","Directory.Read.All"

$users = Get-MgUser -All -Property Id,DisplayName,UserPrincipalName,Department,AssignedLicenses
$signins = Get-MgAuditLogSignIn -All -Filter "createdDateTime ge $(Get-Date).AddDays(-120).ToString('o')"

$lastSignin = $signins | Group-Object UserId | ForEach-Object {
    [PSCustomObject]@{
        UserId      = $_.Name
        LastSignIn  = ($_.Group | Sort-Object CreatedDateTime -Descending | Select-Object -First 1).CreatedDateTime
    }
}

$result = $users | ForEach-Object {
    $ls = $lastSignin | Where-Object {$_.UserId -eq $_.Id} | Select-Object -First 1
    [PSCustomObject]@{
        UserPrincipalName = $_.UserPrincipalName
        DisplayName       = $_.DisplayName
        Department        = $_.Department
        SkuCount          = $_.AssignedLicenses.Count
        LastSignIn        = $ls.LastSignIn
    }
}

$result | Export-Csv .\M365-License-Usage.csv -NoTypeInformation

Step 2: Quick Wins in Azure (30–60 Day Payback)

2.1 Kill and Right-Size Forgotten Compute

Most waste is in compute: VMs, AKS node pools, and PaaS SKUs sized for 2021 traffic that never arrived.

  • Find idle VMs: Use Azure Advisor and VM Insights. Flag VMs with <5% CPU and low network/disk over 30+ days.
  • Right-size: Move from older D-series to B-series or the latest generation. Prioritise VMs > D4 with low utilisation.
  • Schedule non-prod: Implement start/stop schedules for Dev/Test.
    • Use Azure Automation or Logic Apps with tags autoShutdown=true.

Example: Stop non-prod VMs in a resource group at 19:00 using Azure CLI (hook this into Automation):

az vm list -g rg-nonprod-app1 --query "[?powerState=='VM running'].name" -o tsv | `
  ForEach-Object { az vm deallocate -g rg-nonprod-app1 -n $_ }

2.2 Storage and Backup: Silent Cost Bleeders

Storage looks cheap line by line, but it grows quietly. Tackle lifecycle and redundancy.

  • Blob Storage:
    • Enable lifecycle policies: move >90-day-old logs to Cool, >365-day-old to Archive or delete.
    • Stop using GRS for non-critical non-prod. Move to LRS or ZRS where RTO/RPO allows.
  • Azure Backup:
    • Review retention. Many orgs keep 3-year backups of dev VMs they rebuild from code anyway.
    • Create separate backup policies for Prod Critical, Prod Non-Critical, and Non-Prod.

Example lifecycle management rule (JSON) for a log container:

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

2.3 Reservations and Savings Plans (Only Where Stable)

By 2026, Azure Savings Plans are usually better than legacy Reserved Instances, but you still need discipline.

  • Identify workloads with >70% utilisation and stable 12–36 month usage.
  • Use Cost Management > Reservations + Savings recommendations, but sanity-check.
  • Prefer compute savings plans for flexibility across regions and VM families; use reservations only for very fixed workloads (e.g., specific databases).

Rule of thumb: Don’t commit more than 60–70% of your average usage to long-term plans unless the workload is guaranteed (e.g., core line-of-business systems).

Step 3: Microsoft 365 – Licences, Add-Ons, and Sprawl

3.1 Right-Size Your Licence Mix

Many tenants in 2026 are still on “everyone gets E5” because of historic bundle deals. That’s rarely optimal.

  • Segment users into profiles: Information Workers, Frontline, External/Contractors, Service Accounts.
  • Map each profile to a licence baseline, e.g.:
    • Information worker: M365 E3 + targeted add-ons (e.g., Defender for Endpoint P2).
    • Frontline: F3 or F5 Security for those who need advanced protection but not full E5.
    • Service accounts: Exchange Online Plan 1 or app-only access where possible.

Then, build automation to align users with the correct SKU.

Example: Assign an F3 licence based on Department using Entra ID Dynamic Groups and group-based licensing:

(user.department -eq "Warehouse") -or (user.department -eq "Retail")

3.2 Kill Unused & Underused Add-Ons

Add-ons (Viva, extra storage, third-party security) often slip through approvals.

  • List all active add-ons from the Billing > Licences blade in the M365 Admin Center.
  • For each, measure real usage: do you have >60–70% adoption? If not, consider cutting or shrinking.
  • Consolidate overlapping tools: if you’re all-in on Defender Suite, question third-party email security or legacy DLP.

Use Graph to list active subscriptions programmatically for your own reporting:

Connect-MgGraph -Scopes "Directory.Read.All"
Get-MgSubscribedSku | Select-Object SkuPartNumber,ConsumedUnits,PrepaidUnits

3.3 Storage and SharePoint/OneDrive Governance

SharePoint and OneDrive storage costs escalate when they become the dumping ground for everything.

  • Turn on lifecycle policies for inactive sites (e.g., archive or delete after 2–3 years of inactivity with owner approval).
  • Apply retention labels sensibly: avoid “keep forever” defaults for all content.
  • Educate teams on Teams channel lifecycle; archive unused teams instead of leaving them growing.

Target: Reduce total storage growth rate by at least 20–30% over the next 12 months via lifecycle alone.

Step 4: Governance That Keeps Costs Down Automatically

4.1 Azure Policies to Prevent Future Waste

Cleaning once is pointless if your platform keeps creating mess. Use Azure Policy as your cost gatekeeper.

  • Deny creation of premium SKUs in non-prod (e.g., P1/P2 databases, high-tier app services).
  • Restrict VM sizes by environment. For dev/test, allow only B-series and small D-series.
  • Require auto-shutdown on lab and test VMs.

Example policy rule (snippet) to block premium DB SKUs in dev subscriptions:

"if": {
  "allOf": [
    { "field": "type", "equals": "Microsoft.Sql/servers/databases" },
    { "field": "Microsoft.Sql/servers/databases/sku.tier", "equals": "Premium" }
  ]
},
"then": {
  "effect": "deny"
}

4.2 Landing Zones with Guardrails

If you’re still hand-crafting subscriptions in 2026, you’re paying a tax. Use landing zone templates with cost guardrails built-in.

  • Adopt Azure Landing Zone accelerators or your own Bicep/Terraform modules with:
    • Standard tags (env, app, costCenter, owner).
    • Pre-defined policies for SKU restrictions, backup defaults, and diagnostic settings.
    • Default budgets per subscription or per app.

Budget example via Bicep for a non-prod subscription:

resource budget 'Microsoft.Consumption/budgets@2021-10-01' = {
  name: 'nonprod-monthly-budget'
  scope: subscription().id
  properties: {
    category: 'Cost'
    amount: 1000
    timeGrain: 'Monthly'
    timePeriod: {
      startDate: dateTime('2026-01-01T00:00:00Z')
      endDate: dateTime('2028-12-31T00:00:00Z')
    }
    notifications: {
      actualGt80: {
        enabled: true
        operator: 'GreaterThan'
        threshold: 80
        contactEmails: [ '[email protected]' ]
      }
    }
  }
}

4.3 Standard Onboarding/Offboarding for M365

Licence waste often comes from poor joiner/mover/leaver processes.

  • Automate user provisioning via HR-driven workflows (e.g., Entra ID Lifecycle Workflows, Power Automate, or your IAM of choice).
  • When people leave, move mailboxes to shared or inactive mailbox states with cheaper storage tiers, then free the primary licence.
  • For movers, switch licences based on their new department’s profile automatically.

The goal: no manual licence assignments, and no orphaned licences left for months after someone leaves.

Step 5: Make Cost a Monthly Habit, Not a Yearly Panic

5.1 Create a Cloud Cost Review Rhythm

Cloud cost control is a process, not an event. Set up a recurring rhythm with clear ownership.

  • Weekly (Ops): Review new anomalies flagged by Azure Cost Management. Fix obvious misconfigurations quickly.
  • Monthly (IT + Finance): Share top 10 cost drivers, savings realised, and upcoming risks.
  • Quarterly (Architecture): Review architecture patterns for your major apps – see if any are due a modernisation that would significantly reduce costs (e.g., AKS to Azure Container Apps, SQL to PaaS Serverless).

5.2 A Simple Cost KPI Dashboard

Don’t drown in metrics. Track a handful of KPIs that actually drive behaviour:

  • Azure cost per app per month (top 20 apps).
  • Percentage of resources tagged with owner and cost center.
  • Percentage of non-prod resources following schedule (stopped outside business hours).
  • M365 cost per active user (exclude stale/inactive accounts).
  • Licence utilisation rate per SKU (E5, F3, add-ons).

Use Power BI on top of your cost exports to surface these KPIs to both IT and Finance. If it’s visible, it gets attention.

One Concrete Next Step You Can Take This Week

If you do nothing else, run a 90-minute mini cost review this week:

  • Pull Azure: top 10 most expensive resources and top 5 most expensive resource groups.
  • Pull M365: list all SKUs, consumed units, and count of inactive users (no sign-in in 90+ days).
  • Mark 3–5 changes you can implement immediately (e.g., shut down a dev environment at night, reduce backup retention, reclaim licences from ex-employees).

Those first 3–5 actions usually pay for the time you spent on this review several times over. Then you can push for governance and automation to make the savings permanent.