In partnership with

The $400 line

In a recent post, I built a SQL Server lab on Azure across two regions with the help of AI. The scripts worked. The servers came up. Everything looked fine.

Then I reviewed the list of Azure resources the scripts had created. One of them was Azure Bastion, a secure way to connect to virtual machines without exposing them to the internet. It's a great service. But I knew I had never connected through it.

It was going to cost me about $400 a month anyway. So I removed it.

I already had two other ways in. For the deployment, my scripts used SSH and SCP to reach the VMs directly. For everything after that, I used az vm run-command invoke, which runs commands inside a VM through Azure itself, with no open connection needed.

To be fair, my choice isn't free either. SSH to the VMs means each one has a public IP address. That's a small monthly cost of its own, and an open door that needs locking down. For a short-lived lab, I accepted that trade-off on purpose. In production, I wouldn't.

Why it costs money when nobody uses it

Here's the part many people miss. Azure bills Bastion by the hour from the moment it's deployed, whether anyone connects or not. In Microsoft's own words, it's "billed continuously from deployment regardless of usage."

At the time of writing, the Standard tier costs about $0.29 an hour in East US. That's roughly $212 a month for one host. Put one in each region, and you're past $400 before a single login.

That's what I mean by a hidden cost. Not a mistake. Not a bug. Just something running quietly that nobody remembered to question.

1,000+ Proven ChatGPT Prompts That Help You Work 10X Faster

ChatGPT is insanely powerful.

But most people waste 90% of its potential by using it like Google.

These 1,000+ proven ChatGPT prompts fix that and help you work 10X faster.

Sign up for Superhuman AI and get:

  • 1,000+ ready-to-use prompts to solve problems in minutes instead of hours—tested & used by 1M+ professionals

  • Superhuman AI newsletter (3 min daily) so you keep learning new AI tools & tutorials to stay ahead in your career—the prompts are just the beginning

Where hidden costs hide

Bastion is just one example. In almost every Azure environment I review, some of these show up:

  • Stopped VMs that were never deallocated. If you shut down a VM from inside the operating system, Azure still bills the compute. Only "Stopped (deallocated)" stops the meter.

  • Disks left behind. Delete a VM, and its disks often stay. They keep billing even with nothing attached.

  • Public IP addresses reserved for something that no longer exists.

  • Snapshots and old backups nobody remembers taking.

  • Gateways and network services (VPN, NAT, firewalls) sized for a project that ended.

  • Monitoring and log data collected at full detail "just in case", and kept for months.

None of these break anything. That's exactly why nobody notices them. A broken resource gets a ticket. An idle resource gets an invoice.

Two kinds of hidden cost

I think about it in two groups:

  1. What you forgot. Things you deployed on purpose, then moved on from.

  2. What you didn't know you deployed. Things a template, a script, or a wizard created for you. My Bastion was in this group. AI wrote the script, the script included Bastion, and I caught it only because I reviewed the resources it created and knew I had never used that one.

The second group is growing. AI and templates make deployment faster than ever, which also means they can create resources faster than we review them.

The fix isn't a tool. It's a routine.

You can't remove what you can't see. So the first step is always the same: know exactly what you have. Not once, but on a schedule.

Here's the routine I recommend to customers, and use myself:

  1. Inventory. Pull a full list of every resource, in every subscription. Monthly is a good start.

  2. Tag. Every resource gets an owner, a purpose, and, for labs and projects, an end date. No tag, no explanation, it goes on the review list.

  3. Review. Sit down with the owners. For each item on the list, ask one question: does this still need to exist?

  4. Act. Delete what's unused. Deallocate what's paused. Downsize what's oversized. For labs, pick the cheapest option that works (Bastion even has a free Developer tier for simple dev/test access).

  5. Prevent. Set budgets and cost alerts. Review every template or AI-generated script before it runs, resource by resource.

The review step is where experience matters most. A report can tell you a disk has no VM attached. It can't tell you whether that disk holds the only copy of something important. That's a conversation, not a query.

Step one, in practice: Azure Resource Inventory

For the inventory step, I like Azure Resource Inventory (ARI). It's a free, open-source PowerShell module from Microsoft that builds an Excel report of everything in your Azure environment, organized by resource type.

A few things I like about it:

  • It's read-only. It doesn't change anything in your environment.

  • It goes wide. One run can cover a whole tenant, a subscription, a management group, or just one resource group.

  • It draws a picture. Besides the Excel file, it creates a network diagram you can open in draw.io.

  • It can add context. Tags, Azure Advisor recommendations, security findings, and, with an extra module, cost details.

How to run it

You need PowerShell 7 or later and read access to the resources you want to see. Azure Cloud Shell works too.

Install-Module -Name AzureResourceInventory
Import-Module AzureResourceInventory

# Whole tenant, with tags
Invoke-ARI -TenantID <your-tenant-id> -IncludeTags

# One subscription, with cost details (needs the Az.CostManagement module)
Invoke-ARI -TenantID <your-tenant-id> -SubscriptionID <your-subscription-id> -IncludeCosts

The report lands in C:\AzureResourceInventory\ on Windows, or $HOME/AzureResourceInventory/ on Linux and Cloud Shell.

I ran it on my own lab subscription this week. It took about a minute.

On a Mac, you'll see a lot of yellow warnings about auto-fitting columns. I tried to fix them and couldn't, but they only affect formatting. The data in the report is complete.

What to look for first

Open the report and start with these questions:

  • Which resources have no tags, and who owns them?

  • Which VMs are stopped but not deallocated?

  • Which disks and public IPs aren't attached to anything?

  • What did Azure Advisor flag as cost recommendations?

  • Is there anything you don't recognize at all? That's usually the most interesting line.

To make it a routine, ARI can also run on a schedule from an Azure Automation account and save each report to a storage account. Then the inventory is waiting for you every month, instead of depending on you remembering.

What it found in my own lab

Here's the honest part. I'm the person who removed Bastion to save money. I still found three things worth fixing in my own subscription.

Finding 1: VMs off, disks still billing

I deallocate my lab VMs when I'm not using them, so the compute stops billing. But 8 of my 12 disks showed up as "Reserved": still attached to those stopped VMs, and still billing.

The report also flagged something I wasn't looking for: 6 operating system disks on Standard HDD, a configuration Azure plans to retire in September 2028. Not a cost today. A project later, if nobody notices.

Finding 1: 8 of 12 disks Reserved, attached to deallocated VMs

Finding 2: about $50 of disks in one month

The cost tab shows what each resource actually cost. In September, disks alone added up to about $50, across more than 20 lines. Some belonged to lab environments I had already moved on from.

Finding 2: about $50 of disk costs in September

Finding 3: good advice, wrong context

Azure Advisor came back with 185 recommendations, and my Cost score was 40%. Many suggestions were reservations and savings plans, worth up to $5,718 a year.

For a production workload running 24/7, that's great advice. For a lab I build and tear down, it would lock me into paying for capacity I don't use. Advisor sees usage. It doesn't see intent. That part is still our job.

Finding 3: Azure Advisor savings recommendations and score

Bonus: a map of your network

ARI also saves a network diagram. I opened mine in VS Code with the free Draw.io Integration extension, and every VNet, subnet, and VM was already laid out.

ARI network diagram opened in VS Code

One more detail from the run: Azure counted 64 resources, and the report included 57. No tool sees everything. That's another reason the review step needs a person.

Your Friday homework

This applies even if you're not in tech. Think of the streaming services, apps, and subscriptions on your credit card. When did you last list them all and ask, "Do I still need this?"

If you do work in the cloud, try this before next Friday: run one inventory on one subscription, and find one thing you didn't know was there. Then reply and tell me what you found. I read every reply, and the best stories might show up in a future post (with your permission, and no names).

If someone on your team keeps saying "the cloud bill is too high", forward this to them.

Sources

Check the Azure pricing calculator for your region.

Disclaimer: The views expressed in this article are those of the author and do not necessarily reflect the official policy or position of Microsoft. The author is a Microsoft employee. All technical details and product behaviors described are based on publicly available Microsoft documentation as of October 2026 and are intended to provide a high-level overview for educational and architectural planning purposes.