There are three different things people often mean when they say they want to βnukeβ an Azure account:
- Stop billing quickly by canceling the subscription.
- Delete all deployed resources inside a subscription.
- Remove the Microsoft Entra tenant after subscriptions and dependencies are gone.
Do not treat these as the same operation. Azure separates billing, resources, subscriptions, Marketplace products, support plans, and Entra tenants.
This runbook is written for environments you own or administer. It is intentionally defensive: verify the target subscription, back up data first, use confirmation prompts, remove locks deliberately, and handle partial failures without losing track of what remains.
Before You Delete Anything
Make sure you have a real backup of anything you might need later:
- databases
- storage accounts
- virtual machine disks or images
- Key Vault secrets and certificates
- DNS zone records
- application configuration
- CI/CD secrets
- SaaS or Marketplace configuration
- identity tenant settings
If you are cleaning up after an OpenClaw install, verify the backup archive before touching Azure resources:
ls -lh ~/openclaw-backups/*.tar.gz
tar -tzf ~/openclaw-backups/openclaw-state-YYYYMMDD-HHMMSS.tar.gz | head -50
sha256sum -c ~/openclaw-backups/openclaw-backups.sha256A tiny archive may not contain production data. Confirm before deletion.
Option 1: Stop Billing as Fast as Possible
If your main goal is stopping cost, cancel the subscription from the Azure portal:
Azure portal
-> Cost Management + Billing
-> Subscriptions
-> Select subscription
-> CancelMicrosoft documents that after cancellation, billing stops immediately, although the final invoice can still include usage already incurred in the current billing cycle. The subscription and retained data are not deleted immediately.
Also check separately for:
- Marketplace SaaS products
- Azure support plans
- Microsoft 365 or other commercial subscriptions
- third-party services billed outside Azure
Microsoft notes that SaaS subscriptions may need manual cancellation; only pay-as-you-go SaaS subscriptions are automatically canceled by the Azure subscription cancellation process.
Use this option when cost control matters more than immediately purging every resource.
Option 2: Delete All Resources in a Subscription
If you want the subscription empty before canceling or deleting it, delete all resource groups.
Start by identifying the exact subscription:
az login
az account show \
--query '{subscription:name,id:id,tenant:tenantId,user:user.name}' \
--output yaml
az account list \
--query '[].{name:name,id:id,tenant:tenantId,isDefault:isDefault}' \
--output tableSet placeholders for the subscription you intend to delete:
SUB_ID="00000000-0000-0000-0000-000000000000"
EXPECTED_NAME="Your Subscription Name"
EXPECTED_TENANT="11111111-1111-1111-1111-111111111111"Preview resources:
az account set --subscription "$SUB_ID"
az resource list \
--subscription "$SUB_ID" \
--query '[].{name:name,type:type,resourceGroup:resourceGroup}' \
--output table
az group list \
--subscription "$SUB_ID" \
--query '[].name' \
--output tableSafer Deletion Script
Create azure-nuke.sh:
#!/usr/bin/env bash
set -euo pipefail
SUB_ID="00000000-0000-0000-0000-000000000000"
EXPECTED_NAME="Your Subscription Name"
EXPECTED_TENANT="11111111-1111-1111-1111-111111111111"
az account set --subscription "$SUB_ID"
ACTUAL_ID="$(az account show --query id --output tsv)"
ACTUAL_NAME="$(az account show --query name --output tsv)"
ACTUAL_TENANT="$(az account show --query tenantId --output tsv)"
echo
echo "Deletion target"
echo " Subscription: $ACTUAL_NAME"
echo " ID: $ACTUAL_ID"
echo " Tenant: $ACTUAL_TENANT"
echo
if [[ "$ACTUAL_ID" != "$SUB_ID" ||
"$ACTUAL_NAME" != "$EXPECTED_NAME" ||
"$ACTUAL_TENANT" != "$EXPECTED_TENANT" ]]; then
echo "ERROR: Azure context does not match the expected subscription."
exit 1
fi
echo "RESOURCE GROUPS THAT WILL BE DELETED:"
az group list \
--subscription "$SUB_ID" \
--query "[].name" \
--output table
echo
read -r -p "Type exactly 'NUKE $SUB_ID' to continue: " CONFIRM
if [[ "$CONFIRM" != "NUKE $SUB_ID" ]]; then
echo "Aborted."
exit 1
fi
echo
echo "Removing Azure management locks..."
az lock list \
--subscription "$SUB_ID" \
--query "[].id" \
--output tsv |
while IFS= read -r LOCK_ID; do
[[ -z "$LOCK_ID" ]] && continue
echo "Deleting lock: $LOCK_ID"
az lock delete --ids "$LOCK_ID"
done
echo
echo "Submitting resource-group deletions..."
az group list \
--subscription "$SUB_ID" \
--query "[].name" \
--output tsv |
while IFS= read -r RESOURCE_GROUP; do
[[ -z "$RESOURCE_GROUP" ]] && continue
echo "Deleting resource group: $RESOURCE_GROUP"
az group delete \
--subscription "$SUB_ID" \
--name "$RESOURCE_GROUP" \
--yes \
--no-wait
done
echo
echo "All resource-group deletion requests were submitted."
echo "Run the following to inspect what remains:"
echo "az group list --subscription '$SUB_ID' --output table"
echo "az resource list --subscription '$SUB_ID' --output table"Run it:
chmod +x azure-nuke.sh
./azure-nuke.shResource group deletion is irreversible. Microsoft also notes that you must remove underlying resource locks and backup data before deleting a resource group.
Check What Remains
After submitting deletion requests:
az group list \
--subscription "$SUB_ID" \
--query "[].{name:name,state:properties.provisioningState}" \
--output table
az resource list \
--subscription "$SUB_ID" \
--query "[].{name:name,type:type,resourceGroup:resourceGroup}" \
--output table
az lock list \
--subscription "$SUB_ID" \
--output tableIn the Azure portal, also check hidden resources:
Subscriptions
-> Select subscription
-> Resources
-> Manage view
-> Show hidden typesMicrosoft documents that active hidden resources can block subscription deletion.
Handling ScopeLocked Errors
You may see an error like:
(ScopeLocked) The scope '/subscriptions/.../resourceGroups/lab-rg'
cannot perform delete operation because following scope(s) are locked:
'/subscriptions/.../resourceGroups/lab-rg/providers/...'That means a delete lock still exists on the resource group or on a contained resource. A resource-level delete lock can block deleting the whole resource group.
List locks:
az lock list \
--subscription "$SUB_ID" \
--output tableDelete a known lock deliberately:
az lock delete \
--ids "/subscriptions/.../providers/Microsoft.Authorization/locks/LOCK_NAME"Do not remove locks blindly in shared or production environments. Locks often exist to prevent accidental deletion.
DevTest Labs Can Recreate Locks
Azure DevTest Labs can create protected-resource locks. If you remove the locks first and then immediately delete the resource group, the lab may recreate locks before the group deletion succeeds.
Delete the DevTest Lab service first:
az lab delete \
--subscription "$SUB_ID" \
--resource-group "lab-rg" \
--name "lab" \
--yesThen remove leftover locks:
while IFS= read -r LOCK_ID; do
[[ -z "$LOCK_ID" ]] && continue
echo "Deleting lock: $LOCK_ID"
az lock delete --ids "$LOCK_ID"
done < <(
az lock list \
--subscription "$SUB_ID" \
--resource-group "lab-rg" \
--query "[].id" \
--output tsv
)Then delete the group:
az group delete \
--subscription "$SUB_ID" \
--name "lab-rg" \
--yesResume Cleanup Without Stopping at the First Failure
If the first deletion script stops because of set -e, some earlier groups may already have deletion requests submitted while later groups were never processed.
Resume with a loop that logs failures and continues:
while IFS= read -r RG; do
[[ -z "$RG" ]] && continue
echo "Submitting deletion: $RG"
if ! az group delete \
--subscription "$SUB_ID" \
--name "$RG" \
--yes \
--no-wait; then
echo "WARNING: deletion failed for $RG; continuing"
fi
done < <(
az group list \
--subscription "$SUB_ID" \
--query "[].name" \
--output tsv
)This is useful during cleanup because one locked or service-managed resource group should not prevent deletion requests for unrelated groups.
Cancel the Subscription After Cleanup
Do not cancel the subscription until resource deletion requests are submitted and you have checked what remains.
Portal path:
Azure portal
-> Cost Management + Billing
-> Subscriptions
-> Select subscription
-> CancelThe Azure CLI also has a cancellation command, but check its current status in your CLI version before relying on it:
az account subscription cancel \
--subscription-id "$SUB_ID"After cancellation:
- billing stops immediately, according to Microsoft documentation
- a final invoice may still arrive for usage already incurred
- services are disabled
- subscription data is retained temporarily
- manual deletion in the portal becomes available only after the required waiting period and deletion conditions are met
Microsoft documents that the Delete subscription option is available after 3 days for customer-led subscriptions or 7 days for field and partner channel subscriptions, depending on subscription type. Canceled subscriptions are automatically deleted after 90 days.
Delete the Subscription
After the waiting period:
Azure portal
-> Subscriptions
-> Select canceled subscription
-> DeleteIf deletion is blocked:
- verify all resources are gone
- show hidden resource types in the portal
- check for locks
- wait for deletion state to update
- check Marketplace products and support plans
- verify you have the Subscription Owner role
Delete the Entra Tenant Last
Do not delete the Microsoft Entra tenant before cleaning up subscriptions. Active or canceled subscriptions, Marketplace dependencies, enterprise apps, users, service principals, or directory integrations can block tenant deletion.
Safer order:
- Back up data.
- Delete resources.
- Cancel Marketplace SaaS and support plans.
- Cancel every Azure subscription.
- Delete subscriptions after Azure allows it.
- Remove tenant dependencies.
- Delete the Microsoft Entra tenant from the Entra admin center.
Portal path:
Microsoft Entra admin center
-> Microsoft Entra ID
-> Manage tenants
-> Select tenant
-> DeleteIf this is an organizational tenant, coordinate with the tenant administrator. Removing the identity layer too early can make cleanup harder because you may lose access to the resources and billing objects you still need to remove.
Full Cleanup Checklist
Before running deletion:
- Confirm subscription ID, name, and tenant ID.
- Confirm backups are valid.
- Export DNS records if needed.
- Export databases and storage data.
- Save Key Vault material you are legally allowed and technically able to export.
- Check Marketplace and support subscriptions.
- Check hidden resources.
- Confirm no other teams depend on the subscription.
During deletion:
- Remove intentional locks only after confirming ownership.
- Delete service-managed parents before their managed resource groups.
- Use
--no-waitfor bulk resource-group deletion. - Use continuation loops so one failed group does not stop the rest.
After deletion:
- Verify resource groups.
- Verify resources.
- Verify locks.
- Cancel the subscription.
- Wait for manual subscription deletion eligibility.
- Delete the subscription.
- Delete the Entra tenant only after subscriptions and dependencies are gone.
Related Microsoft Documentation
- Cancel and delete your Azure subscription
- Azure Resource Manager resource group and resource deletion
- Lock your Azure resources to protect your infrastructure
- az lab delete
Key Takeaways
Deleting Azure resources, canceling a subscription, deleting a subscription, and deleting an Entra tenant are different operations.
If you want to stop cost quickly, cancel the subscription. If you want a clean subscription before cancellation, delete resource groups first and handle locks, hidden resources, and service-managed groups.
Delete the Entra tenant last. Identity cleanup before resource and billing cleanup can make the remaining work harder.
