{"id":99033,"date":"2023-11-01T20:41:37","date_gmt":"2023-11-01T20:41:37","guid":{"rendered":"https:\/\/www.red-gate.com\/simple-talk\/?p=99033"},"modified":"2023-11-01T20:41:37","modified_gmt":"2023-11-01T20:41:37","slug":"move-disks-or-virtual-machines-between-tenants-on-azure","status":"publish","type":"post","link":"https:\/\/www.red-gate.com\/simple-talk\/blogs\/move-disks-or-virtual-machines-between-tenants-on-azure\/","title":{"rendered":"Move Disks or Virtual Machines between Tenants on Azure"},"content":{"rendered":"<p>Move objects on Azure is not simple. Move between Tenants is extremely difficult or not possible. I faced the challenge to move a virtual machine and disks between tenants recently and found the solution.<\/p>\n<p>Some Years ago, I wrote an article about the <a href=\"https:\/\/www.red-gate.com\/simple-talk\/cloud\/infrastructure-as-a-service\/lets-move-azure-resource-mover\/\">Azure Resource Mover<\/a> when it was still being created. Today the resource mover is integrated with the entire azure portal, although there are already many limitations in relation to moving resources. Anyway, this will not affect us on this blog post.<\/p>\n<h2>Moving Process<\/h2>\n<p>The process is based on moving the disks and creating the VM again on the other tenant.<\/p>\n<p>These steps are for a Virtual Machine with managed disks:<\/p>\n<ol>\n<li>Create a snapshot from each disk<\/li>\n<li>From each snapshot, export it to VHD in a storage account.<\/li>\n<li>Use <strong>AZCOPY<\/strong> to copy the VHDs to a storage on the different tenant<\/li>\n<li>On the marketplace, create a new managed disk and select the option to create it from the VHD<\/li>\n<li>Repeat the step 4 for each VHD<\/li>\n<li>Open the managed disk which contains the operating system<\/li>\n<li>Use the option to create a virtual machine from the disk<\/li>\n<li>Attach the additional managed disks<\/li>\n<\/ol>\n<p>It may appear to be something simple, but this process hides some details which most people don\u2019t know:<\/p>\n<ul>\n<li>A snapshot is managed. Copy a snapshot as a VHD requires a special command<\/li>\n<li>It would be trivial if we could download the VHD and upload on the correct place. But we are talking about disks of 1Tb or more. These disks don\u2019t fit our local environment, we need to transfer directly from one storage to another. AZCOPY has the capability to use a Server-to-Server API to make the transfer, the data doesn\u2019t pass by your local machine.<\/li>\n<li>We can create a Virtual Machine from an existing OS disk if we start the creating from the managed OS disk.<\/li>\n<\/ul>\n<p>Let\u2019s follow the steps and discover the hidden tricks in the way<\/p>\n<h2>Create a snapshot from the disk<\/h2>\n<ol>\n<li>Open the managed disk.<\/li>\n<li>Using the top menu on the managed disk window, click Create Snapshot button<\/li>\n<li>On the Name textbox, provide a name to the disk snapshot.<\/li>\n<\/ol>\n<p>You also can choose the resource group for the disk snapshot. Besides that, the additional properties are only important if you are following some standard from your company, such as security standards.<\/p>\n<p>I will not get into the security details on this blog.<\/p>\n<h2>Export the snapshot to a VHD<\/h2>\n<p>The copy process needs to be done by script. Either Azure CLI or Powershell. I have a personal choice for Powershell.<\/p>\n<p>The script needs to execute three steps:<\/p>\n<ol>\n<li>Use the <strong>Grant-AzSnapshotAccess <\/strong>cmdlet to get access to the snapshot, allowing the copy to happen<\/li>\n<li>Use the <strong>New-AzStorageContext<\/strong> cmdlet to get a context to the destination storage<\/li>\n<li>Use <strong>Start-AzStorageBlobCopy<\/strong> with the result from the two previous commands to execute the copy<\/li>\n<\/ol>\n<p>Let&#8217;s consider the following information to start:<\/p>\n<ul>\n<li><strong>Resource Group name<\/strong>: devMaltaStation_group<\/li>\n<li><strong>Snapshot Name<\/strong>: disksnapshotbackup<\/li>\n<li><strong>Destination Storage account name<\/strong>: devmaltasnapshotexport<\/li>\n<li><strong>Destination container name<\/strong>: snapshots<\/li>\n<\/ul>\n<h2>Step-by-Step Process<\/h2>\n<p>We need to retrieve a key to the destination storage to complete the copy process.<\/p>\n<ol>\n<li>Access the storage account<\/li>\n<li>Click the menu item <em>Access Keys<\/em> on the left side of the window<\/li>\n<li>Click the <em>Show<\/em> button besides the textbox <em>Key<\/em>. It can either be for <em>Key 1<\/em> or <em>Key 2<\/em><\/li>\n<\/ol>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"1009\" height=\"649\" class=\"wp-image-99034\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2023\/11\/word-image-99033-1.png\" \/><\/p>\n<ol>\n<li value=\"4\">Click the <em>Copy<\/em> button besides the key which will be displayed. Save this key, you will need it later.<\/li>\n<li>Open the cloud shell using the button on the top of the window. I provided additional details about the cloud shell in a previous blog (<a href=\"https:\/\/www.red-gate.com\/simple-talk\/blogs\/start-stopping-virtual-machines-resource-group\/\">https:\/\/www.red-gate.com\/simple-talk\/blogs\/start-stopping-virtual-machines-resource-group\/<\/a> )<\/li>\n<\/ol>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"318\" height=\"102\" class=\"wp-image-99035\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2023\/11\/a-black-and-white-screen-with-icons-description-a.png\" alt=\"A black and white screen with icons\n\nDescription automatically generated\" \/><\/p>\n<ol>\n<li value=\"6\">Execute the code below to retrieve an object to access the snapshot<\/li>\n<\/ol>\n<p><!-- HTML generated using hilite.me --><\/p>\n<div style=\"background: #ffffff;overflow: auto;width: auto;border: solid gray;border-width: .1em .1em .1em .8em;padding: .2em .6em\">\n<pre style=\"margin: 0;line-height: 125%\" class=\"crayon:false\"><span style=\"color: #996633\">$sas<\/span>=Grant-AzSnapshotAccess -ResourceGroupname <span style=\"background-color: #fff0f0\">'devMaltaStation_group'<\/span> -SnapshotName <span style=\"background-color: #fff0f0\">'disksnapshotbackup'<\/span> -DurationInSecond 600 -Access Read\r\n<\/pre>\n<\/div>\n<p>You need to be careful with the DurationInSecond parameter. This is the amount of time the access will be allowed. The copy of the file needs to be completed before this amount of time.<\/p>\n<ol>\n<li value=\"7\">Execute the following statement to retrieve a context for the target storage:<\/li>\n<\/ol>\n<p><!-- HTML generated using hilite.me --><\/p>\n<div style=\"background: #ffffff;overflow: auto;width: auto;border: solid gray;border-width: .1em .1em .1em .8em;padding: .2em .6em\">\n<pre style=\"margin: 0;line-height: 125%\" class=\"crayon:false\"><span style=\"color: #996633\">$destinationContext<\/span>= <span style=\"color: #007020\">New-AzStorageContext<\/span> -StorageAccountName <span style=\"background-color: #fff0f0\">'devmaltasnapshotexport'<\/span> -StorageAccountKey <span style=\"background-color: #fff0f0\">'&lt;&lt; the key you saved &gt;&gt;'<\/span>\r\n<\/pre>\n<\/div>\n<p>On this example, we are using a storage key retrieved on the steps 4 to 7. This could be in different ways, using a SAS key or using a connection string. You can check different options on (<a href=\"https:\/\/learn.microsoft.com\/en-us\/powershell\/module\/az.storage\/new-azstoragecontext?view=azps-10.4.1\">https:\/\/learn.microsoft.com\/en-us\/powershell\/module\/az.storage\/new-azstoragecontext?view=azps-10.4.1<\/a> ). Different options would change the steps from 4 to 7.<\/p>\n<ol>\n<li value=\"8\">Execute the statement below to make the copy of the snapshot to the storage account:<\/li>\n<\/ol>\n<p><!-- HTML generated using hilite.me --><\/p>\n<div style=\"background: #ffffff;overflow: auto;width: auto;border: solid gray;border-width: .1em .1em .1em .8em;padding: .2em .6em\">\n<pre style=\"margin: 0;line-height: 125%\" class=\"crayon:false\"><span style=\"color: #007020\">Start-AzStorageBlobCopy<\/span> -AbsoluteUri <span style=\"color: #996633\">$sas<\/span>.AccessSAS -DestContainer <span style=\"background-color: #fff0f0\">'snapshots'<\/span> -DestContext <span style=\"color: #996633\">$destinationContext<\/span> -DestBlob <span style=\"background-color: #fff0f0\">'Disk01.vhd'<\/span>\r\n<\/pre>\n<\/div>\n<ol>\n<li value=\"9\">Repeat the steps 6 to 8 for each snapshot you have, changing the name of the destination file on the step 8.<\/li>\n<\/ol>\n<h2>Use AZCOPY to transfer the snapshot<\/h2>\n<p><strong>AZCOPY<\/strong> uses storage account <strong>SAS<\/strong> keys to access the source and destination storage. Because that, it doesn\u2019t matter if the storage accounts are in the same tenant or not.<\/p>\n<p>The best of it is the fact it uses server API\u2019s for the transfer. In this way the data goes from server to server, without involving your client machine and avoiding a bottleneck.<\/p>\n<p>Retrieving the address and key from the source:<\/p>\n<ol>\n<li value=\"10\">Access the source storage account<\/li>\n<li>Access the container and locate the file<\/li>\n<li>Besides the file, open the expand menu (&#8230;) and click Generate SAS menu option<\/li>\n<\/ol>\n<p>On the new window, the permission and the expiration are the two most important properties you need to handle. The source only needs <em>Read<\/em> permission, but the expiration needs to be enough for the copy<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"687\" height=\"794\" class=\"wp-image-99036\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2023\/11\/a-screenshot-of-a-computer-description-automatica.png\" alt=\"A screenshot of a computer\n\nDescription automatically generated\" \/><\/p>\n<ol>\n<li value=\"13\">Click the <em>Generate SAS token and URL<\/em> button<\/li>\n<li>On the box <em>Blob SAS URL<\/em>, click the <em>Copy<\/em> button<\/li>\n<\/ol>\n<p>This will copy the URL and SAS key together and you will need to use them to build the <strong>AZCOPY<\/strong> statement<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"1432\" height=\"266\" class=\"wp-image-99037\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2023\/11\/a-close-up-of-a-computer-screen-description-autom.png\" alt=\"A close-up of a computer screen\n\nDescription automatically generated\" \/><\/p>\n<p>Retrieving the URL from the target is basically repeating the steps from 13 to 17, with only a few differences:<\/p>\n<ul>\n<li>You will point to a container or folder where the file will be saved<\/li>\n<li>The permission will need to be more than Read.<\/li>\n<\/ul>\n<ol>\n<li value=\"15\">Build the <strong>AZCOPY<\/strong> statement as the format below:<\/li>\n<\/ol>\n<p><!-- HTML generated using hilite.me --><\/p>\n<div style=\"background: #ffffff;overflow: auto;width: auto;border: solid gray;border-width: .1em .1em .1em .8em;padding: .2em .6em\">\n<pre style=\"margin: 0;line-height: 125%\">azcopy cp <span style=\"background-color: #fff0f0\">\"https:\/\/[srcaccount].blob.core.windows.net\/[container]\/[path\/to\/blob]?[SAS]\"<\/span> https<span style=\"color: #ff0000;background-color: #ffaaaa\">:<\/span>\/\/<span style=\"color: #003366;font-weight: bold\">[destaccount]<\/span>.blob.core.windows.net\/<span style=\"color: #003366;font-weight: bold\">[container]<\/span>\/[path\/to\/blob]?<span style=\"color: #003366;font-weight: bold\">[SAS]<\/span>\r\n<\/pre>\n<\/div>\n<p>Use the URLs you retrieved from the source and destination to build this statements<\/p>\n<ol>\n<li value=\"16\">Execute the <strong>AZCOPY<\/strong> on the cloud shell<\/li>\n<\/ol>\n<h2>Create a new Managed Disk<\/h2>\n<ol>\n<li value=\"17\">Access the target resource group<\/li>\n<li>Click the <em>Create<\/em> button to access the marketplace<\/li>\n<\/ol>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"527\" height=\"36\" class=\"wp-image-99038\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2023\/11\/word-image-99033-5.png\" \/><\/p>\n<ol>\n<li value=\"19\">On the marketplace, search for <em>Managed Disk<\/em><\/li>\n<\/ol>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"993\" height=\"618\" class=\"wp-image-99039\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2023\/11\/a-screenshot-of-a-computer-description-automatica-1.png\" alt=\"A screenshot of a computer\n\nDescription automatically generated\" \/><\/p>\n<ol>\n<li value=\"20\">Click the <em>Create<\/em> button<\/li>\n<\/ol>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"464\" height=\"235\" class=\"wp-image-99040\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2023\/11\/a-screenshot-of-a-computer-description-automatica-2.png\" alt=\"A screenshot of a computer\n\nDescription automatically generated\" \/><\/p>\n<ol>\n<li value=\"21\">On the box <em>Source Type<\/em>, select <em>Storage Blob<\/em><\/li>\n<\/ol>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"771\" height=\"837\" class=\"wp-image-99041\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2023\/11\/a-screenshot-of-a-computer-description-automatica-3.png\" alt=\"A screenshot of a computer\n\nDescription automatically generated\" \/><\/p>\n<ol>\n<li value=\"22\">On the box <em>Source Blob<\/em>, click Browse to locate the <em>VHD<\/em> file<\/li>\n<\/ol>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"754\" height=\"53\" class=\"wp-image-99042\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2023\/11\/word-image-99033-9.png\" \/><\/p>\n<ol>\n<li value=\"23\">On the following windows, point to the storage account, container and file<\/li>\n<\/ol>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"657\" height=\"461\" class=\"wp-image-99043\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2023\/11\/a-screenshot-of-a-computer-description-automatica-4.png\" alt=\"A screenshot of a computer\n\nDescription automatically generated\" \/><\/p>\n<ol>\n<li value=\"24\">On the <em>OS Type<\/em> options, select the operating system the disk contains. Otherwise, you can only use it as a data disk.<\/li>\n<\/ol>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"396\" height=\"84\" class=\"wp-image-99044\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2023\/11\/a-white-background-with-black-dots-description-au.png\" alt=\"A white background with black dots\n\nDescription automatically generated\" \/><\/p>\n<ol>\n<li value=\"25\">Select the VM architecture and disk size. This needs to be according to the original disk, otherwise the process will fail.<\/li>\n<\/ol>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"382\" height=\"138\" class=\"wp-image-99045\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2023\/11\/a-white-background-with-a-black-and-white-sign-de.png\" alt=\"A white background with a black and white sign\n\nDescription automatically generated with medium confidence\" \/><\/p>\n<ol>\n<li value=\"26\">Select the disk name, region and availability zone according to how you would like to create the new disk<\/li>\n<\/ol>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"761\" height=\"147\" class=\"wp-image-99046\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2023\/11\/a-screenshot-of-a-computer-description-automatica-5.png\" alt=\"A screenshot of a computer\n\nDescription automatically generated\" \/><\/p>\n<h2>Create a new Virtual Machine<\/h2>\n<p>Once the disks are created, it\u2019s time to create the Virtual Machine. The start of the process is simple: You open the OS disk and click the button to create a virtual machine.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"697\" height=\"126\" class=\"wp-image-99047\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2023\/11\/a-screenshot-of-a-computer-description-automatica-6.png\" alt=\"A screenshot of a computer\n\nDescription automatically generated\" \/><\/p>\n<p>From this point, it\u2019s almost a regular process of VM creation, but with the OS disk already selected. You can attach additional data disks as needed.<\/p>\n<h2>Summary<\/h2>\n<p>This process was very useful for me recently, avoiding making a completely new installation of a virtual machine. It may seem simple, but it\u2019s full of tricks.<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Move objects on Azure is not simple. Move between Tenants is extremely difficult or not possible. I faced the challenge to move a virtual machine and disks between tenants recently and found the solution. Some Years ago, I wrote an article about the Azure Resource Mover when it was still being created. Today the resource&#8230;&hellip;<\/p>\n","protected":false},"author":50808,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[2],"tags":[6071,5364,159043,159042,4635,5893],"coauthors":[6810],"class_list":["post-99033","post","type-post","status-publish","format-standard","hentry","category-blogs","tag-azcopy","tag-azure","tag-azure-resource-mover","tag-managed-disk","tag-powershell","tag-virtual-machine"],"acf":[],"_links":{"self":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/99033","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/users\/50808"}],"replies":[{"embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/comments?post=99033"}],"version-history":[{"count":3,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/99033\/revisions"}],"predecessor-version":[{"id":99050,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/99033\/revisions\/99050"}],"wp:attachment":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/media?parent=99033"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/categories?post=99033"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/tags?post=99033"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/coauthors?post=99033"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}