Azure VMの他テナントへの移行方法

# はじめに
Azure VMをテナントを跨いで移行する機会があったので、その方法について整理してみました。
ちなみに、自宅にオンプレESXiサーバがあるので、そちらに移行する方法もあるなぁと思いましたので、以下に参考としてそのような場合の手順も載せておきます。
VHDファイルのダウンロードに1時間以上かかりそうだったのと、やっぱりクラウド上にある方が何かと便利なので他テナントに移行する方式を取りました。

<details><summary>（参考）自宅のサーバに移行する方法</summary>
ここではローカルにAzure VMのVHDファイルをダウンロードする方法をとる。
対象のVMを停止し「ディスク」タブからエクスポートしたいディスクを選択し「ディスクのエクスポート」を選ぶ。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2475719/d71e0a67-8ae0-57fe-498a-3eb6a14c8859.png)


「データアクセス認証モード」を選択するとEntra ID経由でダウンロードできるが、今回は「安全なURLの生成」から直接ダウンロードする。
「安全なURLの生成」を選択すると以下のような画面になる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2475719/1e9df626-56c1-461a-4969-1f75131e692f.png)

「VHDファイルのダウンロード」を選択するとローカルにダウンロードが開始される。

</details>

なお、テナント内でサブスクリプションを跨いでリソースを移動する時は、以下のようにサブスクリプションの「移動」を行えばよいです（リソースの種類によっては事前準備が必要だが）。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2475719/0128b0cb-87df-0092-d724-efb3eff25bf6.png)

例えばAzure VMのディスクイメージをテナント内の別のサブスクリプションに移動したい場合は以下のような手順を踏むとできるようです。

https://www.aiik.net/2020/07/26/azure-スナップショットで別のサブスクリプションにvm/#toc1

## （本題）他テナントにAzure VMを移行する


https://qiita.com/aktsmm/items/de7bcf68f7f2c0b8beb6#テナントをまたいで-azure-vm-を複製する他の方法

Azureサポートの方が書かれている上記の記事によると大きく2つの方法が考えられるようです。

1. Azure Compute Gallery（Marketplace上にあるサービス）を使う
2. 複製したAzure VMのディスクイメージのVHDファイルを移行先のストレージアカウントにAzcopyでコピーして移行先でVMを復元する

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2475719/8e13b954-afc3-8288-0d35-a6dfa2746e24.png)

今回は、2の方法でやってみます。
Azcopyする時のストレージアカウントはURLでアクセスするため、別のテナントのストレージアカウントでもコピーできるというわけです。

ちなみに、Azure Backupで普通にできそうでは？と思いましたが、テナント内のサブスクリプション移行は可能だがテナント跨ぎはサポートされていないようです。

https://learn.microsoft.com/ja-JP/azure/backup/backup-azure-arm-restore-vms#cross-subscription-restore-preview

> | クロス サブスクリプションの復元 | Azure Virtual Machines またはディスクは復元ポイントから (Azure RBAC 機能に従って) ソース サブスクリプションと同じテナント内の別のサブスクリプションに復元できます。 |
> | --- | --- |

## 手順
1. 移行先でストレージアカウントを作る
2. スナップショットの作成
3. SASの発行
4. Azcopyの実施
5. マネージドディスクの作成
6. 作成したマネージドディスクでVMを作成する

### 移行先でストレージアカウントを作る

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2475719/03e8e322-e730-30fb-5124-a8adbef79a0c.png)


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2475719/4b14e25d-658d-b6c2-e9c5-77b85430866c.png)

課金額が安くなるように以下の設定にする。

- 汎用v2
- LRS
- クール（blobストレージ）

### スナップショットの作成

移行元でVMのディスクイメージのスナップショットを作成します。

対象のVMのディスクイメージの画面

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2475719/ab696f1a-3d8e-9683-b5ec-e0eec9d086ae.png)

「スナップショットの作成」から作成できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2475719/41b0f151-f159-de79-d848-2ff37cc6fc97.png)


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2475719/62d97391-8123-6795-7a37-d76fd98deb97.png)
スナップショットが作成できました。

「スナップショットのエクスポート」タブ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2475719/41d72f53-e009-56fc-c8c5-09674e896fb4.png)
「URLの生成」を選択して発行されたURLがAzcopyで指定するコピー元になります。

### SASの発行

移行先のストレージアカウントでSASを発行し、コピー時の認証情報を取得します。

対象のストレージアカウントの「コンテナ」タブ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2475719/908f2afd-e868-e28a-5ff7-53ba78d03917.png)

「・・・」から「SASの生成」を選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2475719/ed22b3a7-eee0-5e69-fb03-f967009a759f.png)

「アクセス許可」で「読み取り」、「追加」、「作成」、「書き込み」を選択します。
「BLOB SAS URL」をコピーします。

### Azcopyの実施

以下のコマンドを作ってCloudShellで実行します。
※コピー後のVHDのファイル名を入れる必要がある点に注意。

```jsx
azcopy copy ‘コピー元’ ‘https://<ストレージ アカウント名>.blob.core.windows.net/vhds/<コピー後の VHD ファイル名>.vhd?<SAS URL>’
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2475719/57dcae57-bb3c-f5ce-21f3-98d8c2c38234.png)

キタ！しかも早い！127GiBのファイルで5分くらいでした。

### マネージドディスクの作成

移行先でコピーしてきたvhdファイルからマネージドディスクを作成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2475719/f7e8f291-cf44-39da-86de-74e5032aaf19.png)
安くするために「インフラストラクチャ冗長は必要ありません」にしました。
「ソースの種類」で「ストレージBLOB」を選択し先ほどコピーしてきたvhdファイルを選択します。
「OSの種類」は元がLinuxなのでLinuxにしました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2475719/5b8b1926-6c35-b251-40bf-4056d4aa9d20.png)

世代とアーキテクチャは元のディスクの設定を見て、それに合わせました。

サイズの選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2475719/fa40dd9c-4bb3-14e4-011e-3cb22467af5c.png)

元が30GiBなのでサイズは32GiBにしました。
「ストレージの種類」は元が「Premium SSD（LRS）」だったが一番安い「Standard HDD（LRS）」にしました。

### 作成したマネージドディスクでVMを作成する

作成したマネージドディスクの画面からVMを作成します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2475719/d25976bf-3963-a850-a52f-fa2725bb9ac4.png)

VMのサイズは元が「Standard D2s v3」でしたが安い「Standard B2s」にしました。

### 動作確認
VMを起動したところ無事アクセスできました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2475719/0cd43fd0-6b18-d553-55e0-5237688f0aa9.png)
移行元と移行先でカレントディレクトリ内の内容も同じ。
動作も遅いとは感じません。成功！

## エラー対処

```jsx
Marketplace イメージ、または Marketplace イメージをソースとするカスタム イメージから仮想マシンを作成するには、要求にプラン情報が必要です。
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2475719/f0f3c99d-24b6-3bf9-97a4-b4d769e9f0ba.png)

元のイメージが凝った設定をしたかったのかイメージプランという設定値が入っているとそれを指定しないでVMを作成した場合上記のようなエラーが出ました。

[](https://jpaztech1.z11.web.core.windows.net/仮想マシンのデプロイ時にエラーが発生する（VMMarketplaceInvalidInput）.html)

その場合portalから作成することができないのでコマンドで作成します。

```jsx
$DiskName = "azfoopc30"
$rgName = "AZ-foo"
$location = "japaneast"
$nicName = "azfoopc30nic"
$vnetName = "AZ-DefaultVNet"
$ipName = "azfoopc30pip"
$vmName = "AZ-foo-pc30"
$vmSize = "Standard_B2s"
$SubnetName = "AZ-foo-subnet" 

#NICの新規作成

$vnet = Get-AzureRmVirtualNetwork -ResourceGroupName $rgName -Name $vnetName

$pip = New-AzureRmPublicIpAddress -Name $ipName -ResourceGroupName $rgName -Location $location -AllocationMethod Static

$nic = New-AzureRmNetworkInterface -Name $nicName -ResourceGroupName $rgName -Location $location -SubnetId $vnet.Subnets[0].Id -PublicIpAddressId $pip.Id

# 仮想マシン設定の定義

$vm = New-AzureRmVMConfig -Name $vmName -VMSize $vmSize

#ディスクの取得

$osDisk = Get-AzureRmDisk -ResourceGroupName $rgName -DiskName $DiskName

$vm = Set-AzureRmVMOSDisk -VM $vm -ManagedDiskId $osDisk.Id -CreateOption Attach -Linux

#!!!!ここで仮想マシンのプラン情報を設定します

$vm = Set-AzureRmVMPlan -VM $vm -Name "pro-18_04-lts" -Product "0001-com-ubuntu-pro-bionic" -Publisher "canonical" 

# 利用規約の同意
az vm image terms accept --urn canonical:0001-com-ubuntu-pro-bionic:pro-18_04-lts:latest

# 仮想マシンの新規作成

$vm = Add-AzureRmVMNetworkInterface -VM $vm -Id $nic.Id

New-AzureRmVM -VM $vm -ResourceGroupName $rgName -Location $location
```

「利用規約の同意」をしていないと以下のエラーが出てVMが作成できません。

```jsx
ErrorMessage: User failed validation to purchase resources. Error message: 'You have not accepted the legal terms on this subscription
```

また、Azureサブスクリプションを作成して初日にこのコマンドを実行していたため、サブスクリプションに支払方法を登録したにもかかわらず「The 'unknown' payment instrument(s)」だと言われてしまいました。翌日実施したところすんなりVMが作成できました。

```jsx
Offer with PublisherId: 'canonical', OfferId: '0001-com-ubuntu-pro-bionic' cannot be purchased due to validation errors. For more information see details. Correlation Id: '06ff4a9d-212b-4faa-92fc-26a73c058cc0' The 'unknown' payment instrument(s) is not supported for offer with OfferId: '0001-com-ubuntu-pro-bionic', PlanId 'pro-18_04-lts-gen2'. Correlation Id '06ff4a9d-212b-4faa-92fc-26a73c058cc0'.[{"The 'unknown' payment instrument(s) is not supported for offer with OfferId: '0001-com-ubuntu-pro-bionic', PlanId 'pro-18_04-lts-gen2'. Correlation Id '06ff4a9d-212b-4faa-92fc-26a73c058cc0'.":"StoreApi"}] (コード: BadRequest)
```