Meteen naar de inhoud

Move objects automatic through Azure Subscriptions

  • door

In a recent transformation project where the customer had adopted the old management structure of only having three subscriptions (dev, stage, prod) and now was not compliant to Microsoft best practice where it is recommended to have more isolated environments, my and my team was tasked to move or “migrate” the resources to a new subscription.

This can be done in a number of ways, you either click your way trough the portal ticking every resource you want to move or you do it programatically. As our customer had alot of resources ticking each one in the portal can be cumbersome as you can not go to the next page without loosing the “ticks” from the previous page. Anyway this method worked fine in dev but for stage and prod i set out to do it in a more automated manner.

The following Powershell script takes an array of resource group names, builds an object with its resource group name, old ID and new ID. We then use Get-AzResource and filter out any unwanted resource we dont want to move. Keep in mind when moving resources you only move the parent resources and the child resources will be moved automatically hence the need for $_.ParentResource -eq $null.

We then continue to gather all the ID’s for the resources we intend to move and pass them to Invoke-AzResourceAction -Action validateMoveResources to be validated followed by the Move-AzResource command. In the script i choose to execute this command in parallel to save time using Foreach-Object -ThrottleLimit 10 -Parallel. Here is the full script, hope it can help you in your project 🙂

Ps. the script requires you to have Contributor permission in the source and target subscription. Be careful when running this as there is no confirmation before the Move-AzResource cmd, advice you to test it on a non-production resource-group.Connect-AzAccount

$sourceSub = “” #stage
$targetSub = “” #stage

Set-AzContext -Subscription $sourceSub

$rgNames = (“rg1″,”rg2″,”rg3”)

$rgs = @(
)

#Array builder..
foreach ($rg in $rgNames) {
$rgs += [pscustomobject]@{rgName=$rg; oldId=”/subscriptions/$sourceSub/resourceGroups/$rg”; newId=”/subscriptions/$targetSub/resourceGroups/$rg”}
}

$rgs | Foreach-Object -ThrottleLimit 10 -Parallel {
$targetSub = “”
$rgResources = (Get-AzResource -ResourceGroupName $_.rgName) | Where-Object {($_.ParentResource -eq $null) -and ($_.ResourceType -ne “microsoft.alertsmanagement/smartDetectorAlertRules”) }
Write-Host “<<< THESE ARE THE RESOURCES WE WILL MOVE FROM $($_.rgName) >>>”
$rgResources | Format-Table
Invoke-AzResourceAction -Action validateMoveResources -ResourceId $_.oldId -Parameters @{ resources=$rgResources.ResourceId;targetResourceGroup=$_.newId } -Force -ErrorAction Stop
Write-Host “`e[32m$($_.rgName) Was validated OK!`e[0m”
Write-Host “Initating moving of resources in rg: $($_.rgName) to new subscription old-id: $($_.oldId) -> new-id: $($_.newId)”
Move-AzResource -DestinationResourceGroupName $_.rgName -DestinationSubscriptionId $targetSub -ResourceId $rgResources.ResourceId -Force
}

If you find this helpful please consider following me on linkedIn, where i share more tips and tricks and my experiences with working in Azure.