Persistent readers of the blog may recall I did a post recently, where I outlined the only available route to migrate Microsoft Azure Cloud Solutions Provider (CSP) subscriptions from one Azure Active Directory (AAD) tenant to another. The way described in the post is perhaps not the most ideal, mainly due to the number of steps involved, but it is nonetheless a viable route that “works” - I have the battle scars to prove it. đŸ˜… This week, I wanted to expand upon this further by highlighting the sort of things to watch out and plan for as part of a multi-tenant CSP subscription migration.
Not all Azure resources support migration. Period.
This statement is one of the sad facts about any Azure resource migration, whether it’s to another subscription in the same tenant or to somewhere else further afield; some resources just can’t be moved at all. Microsoft maintains a full list of all resources, indicating their appropriate status, which is updated regularly. In my own experience, the main issue I had was around Metric Alerts (activitylogalerts) and Azure AD Domain Services resources. The first of these is more of a minor inconvenience, given how you can straightforwardly recreate these. However, the second example is perhaps far more debilitating, depending on the complexity of your network. Be sure to consult this list closely for each resource you are hoping to move, to flag up any issues along the way.
Prepare for some Azure Key Vault Related Troubles
Azure Key Vault is a fantastic solution to consider if you need to manage secure credentials across multiple environments and grant permissions to managed identity principles within your AAD tenant. It’s also a requirement when working with the Dynamics 365 Customer Engagement Data Export Service. For most migration scenarios, you’ll be pleased to hear that there are no barriers relating to this, thereby allowing you to move this resource and all related secrets, certificates etc. with no issues. However, you will need to run the following PowerShell script, using the Az module, after migration, to ensure that the Key Vault resource is bound to the new AAD tenant successfully:
#Connect and login to Azure
Connect-AzAccount
#Update the below values for your own environment
$kvName = "my-keyvault" #Name of your Key Vault resource
$subscriptionID = "7779a36e-36bb-44d8-bfcc-24d54536999f" #GUID of the subscription where the Key Vault resource resides
#Target the correct subscription
Select-AzSubscription -SubscriptionId $subscriptionID
# Get your key vault's Resource ID
$vaultResourceId = (Get-AzKeyVault -VaultName $kvName).ResourceId
# Get the properties for your key vault
$vault = Get-AzResource –ResourceId $vaultResourceId -ExpandProperties
# Change the Tenant that your key vault resides in
$vault.Properties.TenantId = (Get-AzContext).Tenant.TenantId
# Access policies can be updated with real applications/users/rights so that it does not need to be done after this whole activity.
# Here we are not setting any access policies.
$vault.Properties.AccessPolicies = @()
# Modifies the key vault's properties.
Set-AzResource -ResourceId $vaultResourceId -Properties $vault.Properties
Failing to do this will result in you having no permissions whatsoever to access the Key Vault properties.
An additional thing to point out is that there is a hard restriction on moving any Key Vault resource configured for disk encryption for an Azure Virtual Machine (VM). In this particular scenario, the only recourse is to disable any encryption, delete the Key vault resource, move your VM to its new tenant/subscription and then proceed to recreate anything. This sequence will take considerably longer than running the above PowerShell script and would require thorough testing to achieve successfully.
For Main Course, how about a portion of Azure Data Factory Fiddling?
Similar to Azure Key Vaults, Azure Data Factory can be configured to bind with any underlying AAD tenant closely it is associated with, via a managed identity. A key benefit of this is then allowing you to grant privileges for the data factory to access other resources on the tenant such as, for example, an Azure Key vault secret for a database connection string. As a managed identity is an object existing at the AAD tenant level, this is not factored in as part of any resource migration and is something that requires recreating post-migration. The quickest way of doing this is by running the following PowerShell script, which again uses the Az module:
#Connect and login to Azure
Connect-AzAccount
#Update the below values for your own environment
$rgName = "my-rg" #Name of the ADF's resource group
$dfName = "my-adf" #Name of the ADF resource
$dfLocation = "UK South" #Location of the ADF resource
$subscriptionID = "7779a36e-36bb-44d8-bfcc-24d54536999f" #GUID of the subscription where the Key Vault resource resides
#Target the correct subscription
Select-AzSubscription -SubscriptionId $subscriptionID
#Recreate the managed identity via the Set-AzDataFactoryV2 cmdlet
Set-AzDataFactoryV2 -ResourceGroupName $rgName -Name $dfName -Location $dfLocation
Then, once the managed identity exists on the tenant, you can then proceed to re-assign any privileges that were also present in the old tenant.
SQL Server AAD Admin Strangeness
Another feature which seeks to blend a given Azure resource more closely with an AAD tenant is the ability to access your Azure SQL databases via an AAD login. Having this in place can help significantly in simplifying login procedures, enforcing security and reducing the risk of a potential data breach. A necessary step to setting this up is assigning a single user account in the tenant with global administrator privileges across the SQL Server. Once defined, you can then use this account to start setting up your accounts or, indeed, a single security group containing all of the accounts and shared privileges required.
A strange issue occurs though when moving SQL Server resources that have been configured as described above. Following any migration, any defined Azure SQL administrator will remain configured at the instance level, instead of being removed entirely. While this has the benefit of ensuring that any existing accounts set up on the old tenant still work as expected, you will still need to replace this with a new AAD admin account in the new tenant. If you are also using Security groups to manage access, then an additional requirement will involve a) ensuring that this security group exists in the new tenant and b) dropping & creating the database account manually. The second step is a definite requirement to prevent any potential login issues, as I assume the binding between SQL Server account and AAD Security group is done based on the GUID of the object on the AAD tenant.
Still not using Azure Templates? Why the hell not?!?
Perhaps the greatest boon you can give yourself before starting any migration process is first to extract and define the Azure resources you intend to move, into an Azure Resource Manager Template. Indeed, in the case of recreating any Metric Alerts or in sorting out some of the fiddly problems mentioned with Key Vault/Data Factory, an Azure template deployment would solve all of this in a pinch. Also, you can begin to more easily leverage the benefits that solutions like Azure DevOps can offer your organisation, by allowing you to collaborate over template deployments, automate the validation & testing of any templates and ensure that these are pushed out continuously into your production environments.
Hopefully, some of these pointers will prove useful to those contemplating a similar type of migration. If anyone has any further tips or questions, feel free to leave a comment below!