Purpose of this script
Delete the resource group holding every Azure resource this project created, safely and idempotently, and wait for the deletion to complete.
Just like terraform destroy, this is permanent. Deleting the resource group deletes the PostgreSQL server and every row of data inside it, with no built-in undo. Back up anything that matters first.
Before you run it prerequisites
- Azure CLI installed and authenticated, as an identity with permission to delete the resource group.
- Nothing else — the script itself checks whether the resource group exists before doing anything, so it's safe to run even if you're not sure what state things are in.
Walking through the script PowerShell version
$subscriptionId = Invoke-Az account show @subscriptionArguments --query id --output tsv
Resolves and fixes the subscription ID up front (honoring -Subscription if supplied), so every following command targets exactly one subscription — no ambiguity if you have several.
$exists = Invoke-Az group exists --name $resourceGroup --subscription $subscriptionId --output tsv
if (([string]$exists).Trim() -eq 'false') {
Write-Host "Resource group '$resourceGroup' does not exist... Nothing to delete."
return
}
Makes the script idempotent in the one direction that matters most: running it against an already-deleted (or never-created) resource group is a harmless no-op, not an error. This is the same spirit as terraform destroy gracefully handling a resource that's already gone.
.\utility_scripts\az_delete_resources.ps1 -WhatIf
Built on PowerShell's standard SupportsShouldProcess mechanism — passing -WhatIf prints exactly what would be deleted without touching anything, the closest manual equivalent to terraform plan -destroy's preview, even though it's far less detailed (it names the resource group, not every individual resource inside it).
Invoke-Az group delete --name $resourceGroup --subscription $subscriptionId --yes
--yes skips Azure CLI's own interactive confirmation prompt (the script's own -WhatIf support is the safety check instead). By default, az group delete blocks until the deletion actually finishes — which can take several minutes, mostly waiting on the PostgreSQL server — so the script (and whoever's running it) knows deletion is complete before moving on, rather than returning immediately while Azure is still cleaning up in the background.
How this compares to terraform destroy same idea, blunter tool
terraform destroy deletes resources one by one, in an order that respects the dependencies Terraform's state already tracks, and shows a plan of exactly what will go before it happens. This script deletes the entire resource group in a single Azure operation — simpler to read and run, but all-or-nothing: there's no way to preview individual resources, and no way to delete just one resource this way without deleting everything alongside it.
Because this script deletes by resource group rather than by tracked resource, it also works correctly regardless of how those resources were created — by this script, by Terraform, or by hand in the Portal. Terraform's own destroy, by contrast, only removes what's in its state file.
Common errors and how to fix them
| What you see | Likely cause | How to fix it |
|---|---|---|
| “No Azure subscription was found” | Not logged in, or no subscription is selected. | Run az login, and pass -Subscription if you have more than one. |
| “Resource group ... does not exist. Nothing to delete.” | This is expected, successful behavior — there was nothing to remove. | No action needed. |
| Authorization error during deletion | Your identity doesn't have delete permission on the resource group. | Use an account with at least Contributor-level access on the subscription or resource group. |
| The command takes several minutes to return | This is expected — the script waits for the full deletion (especially the PostgreSQL server) to complete. | Let it finish; avoid interrupting it partway through. |