How to delete resources of an Azure subscription level deployment - azure

Is there a recommended and deterministic way to delete resources created by a subscription level deployment ?
So far I see a straightforward way only when the subscription level deployment contains a single resource group. In that case deleting the RG will correctly delete all the resources.
However, if there are several RG-s created by the subscription level deployment, the order of deleting them should be driven by dependency order, and discovering that is not easy.
Further on, the subscription level deployment may create other resources as well, listed here.
I could not find any good method for that so far.

Azure don't have any way to delete the resources that were deployed at subscription level deployment directly.
Alternative way that you can look for
Deployments-Get API will give you the resource ids that were deployed as part of deployment.
GET https://management.azure.com/subscriptions/{subscriptionId}/resourcegroups/{resourceGroupName}/providers/Microsoft.Resources/deployments/{deploymentName}?api-version=2021-04-01
collect all the resource ids from (1)
Use 'Resources - Delete By Id' API to delete resource ids (from 2)
DELETE https://management.azure.com/{resourceId}?api-version=2021-04-01
You can use above approach/logic to build a script or a piece of code to automate whole process.

The resources are generally stored in the order they were deployed. For example, the array of resources in the deployment object would be in the order the resources were deployed. If you delete the resources in the reverse order, This could prevent the deletion from failing.
As stated in the other answer, you can get the deployment, get the resources, reverse the order of the resources, and then delete them by their ID. This is not a foolproof method but it would work in many cases.
For example, here is a bash script that will delete all resources deployed in a subscription level deployment that has name 'deploymentName'. The array of resources is reversed, thus the resources are deleted in the reverse order that they were created (i.e. the last resource created is the first one deleted):
az deployment sub list --query "[? name=='deploymentName'].properties.outputResources[::-1].id" --output tsv | tr $'\t' $'\n' | xargs -d $'\n' -otl az resource delete --ids

Related

AzureTag Policy automation using AzureDevops pipelines

We have a requirement to force certain tags to our azure resources. Some tags which we need to enforce from subscription level say(eg: st1=st1, st2=st2..), But some are needed to be resourcegroup level(rt1-rt1, rt2=rt2..) and others are to specific resource type (like, aks, appservice, storage account).
By going through the MS doc I found that this can be achieved using azure policy. So the plan is to create azure policy with allowed tags and tag values which need to be enforced on
i) in subscription level
2) resource group level
3) Resource type wise
4) and for other remaining app specific tags to the resources use "az tag update" command.
We need to use automated solution to achieve all these with Azurepipleine and shell commands or scripts as we have only linux machines.
so for the 4th point i got some working pipeline solution to add the app specific tags to the resource level.
But for the requirements 1 to 3, will there any arm or script already available , so that we can integrate them with our azurepipelines.
Any automated solution or suggestion you already tried on this?
update on 12/12
As this docs for Use Tags to organize your azure resources sharing to us, you could use rest api or sdk to add the tags for your resource.
And for the loop for giving the resources with the tags from the resource groups. You could look into this potential workaround for reference. Bash Script

AKS template creates new resource groups

When I create an AKS cluster using Azure portal I can see that new resource groups are created. It seems that I have no control over how they are named, especially the one with with "MC_" prefix. I also don't see an option to change its name when using ARM template.
In addition, if I create a cluster in customer's subscription, where I only have access to 1 resource group, I don't even see the newly created RG and can't manage it.
Is there a way to force deployment of all AKS components into a single resource group?
No, there is no way to force it at this point in time. As for the access, you should request access to that RG. No real workarounds.
Secondary resource group name can be inferred, I think, its something like:
MC_original-resource-group-name_aks-resource-name_location
it also creates OMS resource group (if you enable OMS) and Network Watcher (this can be disabled, btw, but its a provider setting). you have no control over that as well.
there is a not implemented yet nodeResourceGroup property: https://learn.microsoft.com/en-us/rest/api/aks/managedclusters/createorupdate#examples
EDIT: this is actually working right now, so the nodeResourceGroup property can be used. But it would still be a new resource group, so you would still need to request access to that group and using this property is not possible with the portal (so ARM Templates\pulumi\terraform)

Move Azure resources to another subscription using Powershell

I am attempting to move a resource group (that contains a VM with its dependant resources e.g. network interface etc) to a new subscription and resource group. (the move works fine if done via the GUI)
My Script:
foreach ($resource in $resources) {Move-AzureRmResource
-DestinationResourceGroupName "newresourcegroup" -ResourceId $resource.resourceID -DestinationSubscriptionId 123456}
Its failing with
Move-AzureRmResource :
{"error":{"code":"ResourceMoveProviderValidationFailed","message":"Resource
move validation failed. Please see details. Diagnostic information:
timestamp
etc...
"The move resources request does not contain all the dependent
resources. Please check error details for missing resource
ids.\"}],\"code\":\"MissingMoveDependentResources\",\"message\":\"The
move resources request does not contain all the dependent resources.
Please check error details for missing resource
ids.\"}}"},{"target":"Microsoft.Network/networkInterfaces","message":"{\"error\":{\"code\":\"MissingMoveDependentResources\",\"message\":\"The
move resources request does not contain all the dependent resources.
Please check details for missing resource Ids
Clearly I need to specify the dependant resources somehow, but there doesn't appear to be a parameter for "dependant resources" for the Move-AzureRmResource module.
a. How can I determine what the dependant resources are?
b. How do I specify them in the move cmdlet?
The move resources request does not contain all the dependent resources
According to your scripts, it seems that you just traverse through resources and move them one by one to another resource group in new subscription. But as we know, some resource may have some dependent resources, to move this type of resource (such as virtual machine etc), we should make sure we also move all of the dependent resources, otherwise, the move operation will fail.
Before moving services, we need to know what services that enable move and limitations. Besides, please refer to Use Powershell to move a VM to know how to move resource that requires the dependent resources.
I would add that a move to a new subscription requires that dependent resources be moved at the same time. This requires first organizing resources in the same RG (at this time anyway) before the move operation can succeed. If you are merely moving resources between RGs, then you could do the move without a re-org in your RGs. Remember you may have VM extensions that are hidden objects that can fail, and things like Azure Backup that would need to be addressed before and after the move.
Answer:Here is a REST validation that can be performed to identify dependent resources before attempting the move.
https://learn.microsoft.com/en-us/rest/api/resources/resources/validatemoveresources
You could then get the Resource IDs using: "$Ids = Get-AzureRMResource -ResourceGroupName $sourceRgName.ResourceGroupName | Select-Object ResourceId" then move using "Move-AzureRmResource -DestinationResourceGroupName $targetRg.ResourceGroupName
-DestinationSubscriptionId $AzureTargetSubscription.SubscriptionId
-ResourceId $Ids.ResourceID"

Can't move Webapp to new resource group

I successfully moved several resources via REST API into other resource groups (using this howto) but it failed when I tried to move a WebApp and its service plan. I know there are limitations: I have to move the entire resource group and the target resource group mustn't contain a WebApp. So my target resource group is empty and my source resource group only contains the WebApp and the service plan.
As suggested in the howto, I wrote this JSON:
{
"targetResourceGroup": "/subscriptions/Subscription-B/resourceGroups/newRG",
"resources": [
"/subscriptions/Subscription-A/resourceGroups/oldRG/providers/Microsoft.Web/serverFarms/test",
"/subscriptions/Subscription-A/resourceGroups/oldRG/providers/Microsoft.Web/sites/test"
]
}
and run it via command:
armclient post https://management.azure.com/subscriptions/Subscription-A/resourceGroups/oldRG/moveResources?api-version=2015-01-01 #path/to/my/json -verbose
I get "202: accepted" in the command window and in the portal I see in both resource groups (oldRG and newRG) the info text "resources being moved" but after a minute, nothing has changed.
Edit:
When I click on "delete" in the oldRG, I see all the contained ressources: there are 4 alertrules, 1 autoscalesetting and 1 certificate.
As mentioned in the limitations, I have to move all of them. But how can I access these 3 types of ressources? I don't have their ressource ID because I don't find them when I search for them.
The certificate resource Id looks like:
/subscriptions/Subscription-A/resourceGroups/oldRG/providers/Microsoft.Web/certificates/<certificateThumbprint>
You don't have to pass in autoscale settings or alert rules.
The solution was a combination of Zain Rizvi's answer and this:
I thought it does not matter, that's why I told you the names of the both resource groups are oldRG and newRG - but actually they have the same name. That was the problem. Even if they are in different subscriptions, I wasn't able to move my resources into a resource-group with the same name as the current resource has. So I created a new empty resourcegroup (tmpRG) inside subscriptionB and moved my resources from subscriptionA\myRG to subscriptionB\tmpRG and then from subscriptionB\tmpRG to subscriptionB\myRG.

How do I change the name of an Azure Resource Group?

After the new model was implemented, all of my websites now belong to individual Resource Groups called "Default-Web-East" and all of my SQL databases belong to individual Resource Groups called "Default-SQL-East".
This is confusing to say the least.
I would like to rename the groups to have some semantic meaning. I would also like to group the associated SQL database and Web Site in the same Resource Group.
However, I do not see anyway to do either. Is this possible?
1) Rename the Resource Group?
2) Combine an existing SQL DB and Website together into one Resource Group?
Edit: You can't rename an Azure Resource Group.
What you can do is move your resources to a new Resource Group instead. Moving all resources in Resource Group A to Resource Group B is the poor man's rename.
Unfortunately not all resource providers let you move resources between resource groups, and some that do might have strings attached that only let you move resources under certain conditions.
For Azure Web Apps (previously called Azure Websites) you can currently only move all the websites related resources in a single invocation. That "all websites related resources" means all resource under the provider "Microsoft.Web". This includes all websites, app hosting platforms, and certificates that are in the source resource group.
Via the portal
When viewing a group's resources, you can use the "Move" tab
Clicking the "Move" tab will show something this, allowing you to choose or create a new group:
Via Azure Powershell
The easiest way to do this is to use the Move-AzureRmResource powershell cmdlet.
The command would look like this:
Get-AzureRmResource -ResourceGroupName <sourceResourceGroupName> | Move-AzureRmResource -DestinationResourceGroupName <destResourceGroupName>
source: https://azure.microsoft.com/en-us/documentation/articles/resource-group-move-resources/
Via Rest API
The other way to do this is to use the MoveResource Rest API or with the ArmClient.
Here's the API call you'll want to make:
POST https://<endpoint>/subscriptions/{subscriptionId}/resourcegroups/{resourceGroupName}/moveResources?api-version={api-version}
Where {resourceGroupName} is the source resource group.
I'm pretty sure the endpoint should be "https://management.azure.com", but if you use the ArmClient the tool will just take care of the endpoint for you.
Request Body:
{
"targetResourceGroup": "/subscriptions/{subscriptionId}/resourceGroups/{targetResourceGroupNameName}",
"resources":
[
"/subscriptions/{id}/resourceGroups/{source}/providers/{namespace}/{type}/{name}",
"/subscriptions/{id}/resourceGroups/{source}/providers/{namespace}/{type}/{name}"
]
}
In addition to the main answer, Azure Portal has a feature of moving the Resources that is allowed to be moved to a new Resource group.
Go to your Resource Group that has Resources you want to move to an existing or a new created Resource Group.
Select the one, multiple or all (1) Resources you want to move and click on the Move (2) bottom as shown in image. (you can select moving to Resources with in the same subscription or to another subscription) A third option if you need just to change the Region) see the the figure at the end.
It will ask you to chose which Resource Group to move to.
Note: This process might take some time, be patient. When done, you
will see that the resource disappear from the old one and will be
found in the new one. That said some resources might be restricted
from been moved to other resources.
Move (Fixing) only region

Resources