Azure VM環境をManaged Disksを使って別なサブスクリプションに移行してみた

無料試用版で[機械学習をする環境を作っていた](https://qiita.com/yuni/items/4a823c6ddfd4776cbf4a)のですが、それとは別で使える環境を頂いたので、これまで作ったVM環境を移行します。

基本的にこの記事を参考にしました。
https://blogs.technet.microsoft.com/jpaztech/2017/08/17/export-managed-disks-to-vhd/
やり方は色々とあるようですが、VMを作るときに管理ディスクの機能を使っていたら、このやり方がいいよと教えていただいたので、さっそくやってみます。

Azure CLIを使ってやってみました。

###Azure CLIのインストール
Azure CLIを入れていなかったのでインストールします。

```
brew update && brew install azure-cli
```

###VHDとしてエクスポート
VHD(Virtual Hard Disk)にエクスポートします。

```
$az disk grant-access --duration-in-seconds 3600 --name <ディスク名> --resource-group <リソースグループ名>
```
コマンド叩いたら怒られました。

```
Resource group <リソースグループ名> could not be found.
```
なんで？リソースグルプ名間違ってないのに。と思って調べたら、複数のサブスクリプションがある場合は、１つ目のサブスクリプションのリソースグループしか見てくれないみたいです。

アカウントリストを確認してみます。

```
$az account list
[
  {
    "cloudName": "AzureCloud",
    "id": "XXXXX",
    "isDefault": true,
    "name": "XXXXX",
    "state": "Enabled",
    "tenantId": "XXXXX",
    "user": {
      "name": "XXXXX@gmail.com",
      "type": "user"
    }
  },
  {
    "cloudName": "AzureCloud",
    "id": "XXXXX",
    "isDefault": false,
    "name": "XXXXX",
    "state": "Enabled",
    "tenantId": "XXXXX",
    "user": {
      "name": "XXXXX@gmail.com",
      "type": "user"
    }
  }
]
```
私は２つサブスクリプションがあって、２つ目の方に既にVM環境を構築していたので、そちらにサブスクリプションを切り替えます。
```isDefault": true```
になっているのが現在みているサブスクリプションになります。

```
az account set --subscription <サブスクリプションID>
```
<サブスクリプションID>にはaccount listで取得した"ID"をいれます。
変更できたようなので、管理ディスク (Managed Disks) をVHDにエクスポートします。

```
$az disk grant-access --duration-in-seconds 3600 --name <ディスク名> --resource-group <リソースグループ名>
{
  "accessSas": "https://XXXXX",
  "additionalProperties": {
    "endTime": "2018-04-14T13:04:24.863178+00:00",
    "name": "XXXXX",
    "startTime": "2018-04-14T13:04:24.5037834+00:00",
    "status": "Succeeded"
  }
}
```

###移行先のサブスクリプションにストレージを作成
Azureポータルからストレージアカウント作成しましたが、割愛。

###指定したストレージにVHDをエクスポート
下記コマンド叩いたら怒られた。

```
$az storage blob copy start --account-name <コピー先ストレージ アカウント名> --account-key <コピー先ストレージのアクセス キー> --destination-container <コピー先のコンテナー名> --destination-blob <コピー後の VHD 名>.vhd --source-uri "生成した accessSas の URL"
Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature.ErrorCode: CannotVerifyCopySource
<?xml version="1.0" encoding="utf-8"?><Error><Code>CannotVerifyCopySource</Code><Message>Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature.
RequestId:XXXXX
Time:2018-04-14T14:25:59.1196642Z</Message></Error>
Traceback (most recent call last):
  File "/usr/local/Cellar/azure-cli/2.0.31/libexec/lib/python3.6/site-packages/knack/cli.py", line 197, in invoke
    cmd_result = self.invocation.execute(args)
  File "/usr/local/Cellar/azure-cli/2.0.31/libexec/lib/python3.6/site-packages/azure/cli/core/commands/__init__.py", line 347, in execute
    six.reraise(*sys.exc_info())
  File "/usr/local/Cellar/azure-cli/2.0.31/libexec/lib/python3.6/site-packages/six.py", line 693, in reraise
    raise value
  File "/usr/local/Cellar/azure-cli/2.0.31/libexec/lib/python3.6/site-packages/azure/cli/core/commands/__init__.py", line 319, in execute
    result = cmd(params)
  File "/usr/local/Cellar/azure-cli/2.0.31/libexec/lib/python3.6/site-packages/azure/cli/core/commands/__init__.py", line 180, in __call__
    return super(AzCliCommand, self).__call__(*args, **kwargs)
  File "/usr/local/Cellar/azure-cli/2.0.31/libexec/lib/python3.6/site-packages/knack/commands.py", line 109, in __call__
    return self.handler(*args, **kwargs)
  File "/usr/local/Cellar/azure-cli/2.0.31/libexec/lib/python3.6/site-packages/azure/cli/core/__init__.py", line 420, in default_command_handler
    result = op(**command_args)
  File "/usr/local/Cellar/azure-cli/2.0.31/libexec/lib/python3.6/site-packages/azure/multiapi/storage/v2017_07_29/blob/baseblobservice.py", line 3032, in copy_blob
    False)
  File "/usr/local/Cellar/azure-cli/2.0.31/libexec/lib/python3.6/site-packages/azure/multiapi/storage/v2017_07_29/blob/baseblobservice.py", line 3102, in _copy_blob
    return self._perform_request(request, _parse_properties, [BlobProperties]).copy
  File "/usr/local/Cellar/azure-cli/2.0.31/libexec/lib/python3.6/site-packages/azure/multiapi/storage/v2017_07_29/common/storageclient.py", line 354, in _perform_request
    raise ex
  File "/usr/local/Cellar/azure-cli/2.0.31/libexec/lib/python3.6/site-packages/azure/multiapi/storage/v2017_07_29/common/storageclient.py", line 289, in _perform_request
    raise ex
  File "/usr/local/Cellar/azure-cli/2.0.31/libexec/lib/python3.6/site-packages/azure/multiapi/storage/v2017_07_29/common/storageclient.py", line 275, in _perform_request
    HTTPError(response.status, response.message, response.headers, response.body))
  File "/usr/local/Cellar/azure-cli/2.0.31/libexec/lib/python3.6/site-packages/azure/multiapi/storage/v2017_07_29/common/_error.py", line 111, in _http_error_handler
    raise AzureHttpError(message, http_error.status)
azure.common.AzureHttpError: Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature.ErrorCode: CannotVerifyCopySource
<?xml version="1.0" encoding="utf-8"?><Error><Code>CannotVerifyCopySource</Code><Message>Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature.
RequestId:XXXXX
Time:2018-04-14T14:25:59.1196642Z</Message></Error>
```
VHDにエクスポートした時のSASのアクセス権が1時間しかないみたいで、ストレージアカウント作ったりしてるうちに切れてたみたい。
再度VHDとしてエクスポートして、同じコマンド叩いてみたら無事成功しました。

###VHDから管理ディスクを作成し、VMを作成
VHDから管理ディスクを作成します。
VHDのURLってどこで確認できるんだろって思ったら、
ポータルから、```ストレージアカウント > コンテナ > 概要```で確認できました。
さて、管理ディスクの作成。

```
az disk create --resource-group "リソース グループ名" --name "作成する管理ディスク名" --source "VHD のフル URL" --sku "Premium_LRS or Standard_LRS"
{
  "additionalProperties": {},
  "creationData": {
    "additionalProperties": {},
    "createOption": "Import",
    "imageReference": null,
    "sourceResourceId": null,
    "sourceUri": "https://XXXXX.vhd",
    "storageAccountId": null
  },
  "diskSizeGb": 30,
  "encryptionSettings": null,
  "id": "XXXXX",
  "location": "japaneast",
  "managedBy": null,
  "name": "MLVM",
  "osType": null,
  "provisioningState": "Succeeded",
  "resourceGroup": "yuni",
  "sku": {
    "additionalProperties": {},
    "name": "Standard_LRS",
    "tier": "Standard"
  },
  "tags": {},
  "timeCreated": "2018-04-15T00:30:52.522448+00:00",
  "type": "Microsoft.Compute/disks",
  "zones": null
}
```
こんな感じ。
さてさて、ようやくVMの作成ができます。

```
az vm create --name "VM 名" --resource-group "リソース グループ名" --attach-os-disk "管理ディスク名" --size "VM のサイズ" --os-type "Windows or Linux"
{
  "fqdns": "",
  "id": "XXXXX",
  "location": "japaneast",
  "macAddress": "XXXXX",
  "powerState": "VM running",
  "privateIpAddress": "XXXXX",
  "publicIpAddress": "XXXXX",
  "resourceGroup": ""XXXXX,
  "zones": ""
}
```
できました。
ポータルから確認してもVMの所に移行されたVMができあがってました！ぱちぱち