user3622142
user3622142

Reputation: 370

Azure CLI - Delete resource without deleting resource group

The goal is to delete all resources in a resourcegroup without deleting it using azure CLI.

From reading the doc, I can do this:

az resource delete -g MyResourceGroup -n MyVm

Therefore I assumed I can do the following

az resource list   --resource-group MyResourceGroup | az resource delete 

A similar command in Azure Powershell would work like the above. I am quite new to CLI, is this method possible? What is the efficient way of removing all resources in a resource group (if we have multiple types of resources)

Upvotes: 6

Views: 8812

Answers (3)

catwith
catwith

Reputation: 1275

Here is another simple command:

az resource delete --ids $(az resource list -g <resouce-group-name> --query "[].id" -o tsv)

The command has two parts:

  • az resource delete --ids <list-of-resource-ids>: this deletes all resources of passed ids
  • az resource list -g <resouce-group-name> --query "[].id" -o tsv: this fetches a list of resource ids within a given resource group, each separated by a newline

Upvotes: 1

Luis Cantero
Luis Cantero

Reputation: 1288

There is a faster and simpler approach:

az deployment group create --mode complete --template-uri data:application/json,%7B%22%24schema%22%3A%22https%3A%2F%2Fschema.management.azure.com%2Fschemas%2F2019-04-01%2FdeploymentTemplate.json%23%22%2C%22contentVersion%22%3A%221.0.0.0%22%2C%22resources%22%3A%5B%5D%7D --name clear-resources --resource-group <RG_NAME>

The above data URI (which may also be Base64-encoded) represents this file:

{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"resources": []
}

In an Azure DevOps pipeline you have to pass an actual file with the JSON contents above as DevOps only allows HTTP(s) schemes with --template-uri:

az deployment group create --mode complete --template-file ./clear-resources.json --resource-group <RG_NAME>

Upvotes: 5

RoadRunner
RoadRunner

Reputation: 26315

If can you run Azure CLI in powershell, you could use ConvertFrom-Json to convert the JSON result to a list of objects from az resource list, then run az resource delete on each object id using a foreach loop.

$resources = az resource list --resource-group myResourceGroup | ConvertFrom-Json

foreach ($resource in $resources) {
    az resource delete --resource-group myResourceGroup --ids $resource.id --verbose
}

We could also run this entirely in the pipeline using Foreach-Object, which is close to what you are trying to do.

az resource list --resource-group myResourceGroup 
    | ConvertFrom-Json
        | Foreach-Object {az resource delete --resource-group myResourceGroup --ids $_.id --verbose}

If you don't want to use powershell at all, we can use bash to parse the JSON output ourselves using grep and awk.

#!/bin/bash

resources="$(az resource list --resource-group myResourceGroup | grep id | awk -F \" '{print $4}')"

for id in $resources; do
    az resource delete --resource-group myResourceGroup --ids "$id" --verbose
done

As @Hong Ooi helpfully pointed out in the comments, the main issue with the above is that some resources depend on other resources, so order of deletion matters. One example is that you cannot delete virtual machine disks before the virtual machine is deleted.

To get around this, we could define an ordering of resource types in which to delete resources, as shown in the example hash table below:

$resourceOrderRemovalOrder = [ordered]@{
    "Microsoft.Compute/virtualMachines" = 0
    "Microsoft.Compute/disks" = 1
    "Microsoft.Network/networkInterfaces" = 2
    "Microsoft.Network/publicIpAddresses" = 3
    "Microsoft.Network/networkSecurityGroups" = 4
    "Microsoft.Network/virtualNetworks" = 5
}

Then sort the resources by their resource types and delete them:

$resources = az resource list --resource-group myResourceGroup | ConvertFrom-Json

$orderedResources = $resources 
    | Sort-Object @{
        Expression = {$resourceOrderRemovalOrder[$_.type]}
        Descending = $False
    }

$orderedResources | ForEach-Object {
    az resource delete --resource-group myResourceGroup --ids $_.id --verbose
}

Or in one pipeline if you prefer:

az resource list --resource-group myResourceGroup 
    | ConvertFrom-Json
        | Sort-Object @{Expression = {$resourceOrderRemovalOrder[$_.type]}; Descending = $False}
            | ForEach-Object {az resource delete --resource-group myResourceGroup --ids $_.id --verbose}

Upvotes: 8

Related Questions