Azcopy で SAS を使って Azure VM を別テナントに複製する - その２


こんにちは、アーキテクトのやまぱんです。
補足コメントや質問、**<font color="red">いいね、拡散</font>、是非お願いします🥺**！
間違ってたら<font color="red">優しく</font>教えてください！


# モチベーション
以前下記の記事を書きました

https://qiita.com/aktsmm/items/657c58011577d4001bdb

こちらの方法の手順はざっくり以下です。
+ ソース環境のマネージドディスクからスナップショットの作成
+ ソース環境のスナップショットのエクスポート用 SAS を発行
+ ターゲット環境のストレージ アカウントのアップロード用 SAS を発行
+ 作成したそれぞれの SAS を使って Azcopy 
   ```azcopy copy ‘<ソース SAS>’ ‘<ターゲットSAS>’```
+ ターゲット環境のストレージ アカウントに作成された VHD からマネージドディスクを作成
+ 作成されたマネージドディスクから Azure VM を作成

**この方法では以下の問題が発生します。**
8 TiB (8192GiB) 以上の容量のディスクではストレージ アカウント(BLOB ストレージ) の仕様に抵触して失敗します。

> Azure でサポートされている最大ページ BLOB サイズは、8 TB (8,191 GiB) です。
+ サポートされている最大ページ BLOB サイズはどれくらいですか? - ディスクに関してよく寄せられる質問 - Azure Virtual Machines | Microsoft Learn

https://learn.microsoft.com/ja-jp/azure/virtual-machines/faq-for-disks?tabs=azure-portal#---------------blob--------------

なので、8 TiB (8192GiB) 以上の容量のディスクを別テナントにコピーするには ストレージ アカウントに VHD を作成する以前の方法以外の方法が必要になりました。

:::note warn
補足：以前のストレージ アカウントに Azcopy を使って VHD を作成する方法だと 8 TiB (8192GiB) 以上のディスクでは失敗する
参考までに実際に8 TiB (8192GiB) 以上のディスクで実施してエラーになったときの画面です
+ ローカル環境での Azure PowerShell で実施
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2982508/ba20255f-7136-5a31-7821-8371bf5d3744.png)
+ Cloud Shell 環境での Azure PowerShell で実施
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2982508/3a68c48a-9146-6116-bb3f-428ece5d507f.png)
:::

# 方法概略
ざっくりと以下の手順で可能です。
+ ソース環境でのコピーしたいディスクのスナップショットの SAS 発行 (<ソース SAS>)
+ ターゲット環境で空のマネージドディスクの作成 (データのUpload 可能な状態で作成)
+ ターゲット環境で空のマネージドディスクの SAS 発行　(<ターゲットSAS>)
+ Azcopy  ```azcopy copy ‘<ソース SAS>’ ‘<ターゲットSAS>’```
+ SAS の無効化 / マネージドディスクのステータス変更

主に下記の MS Learn が参考になります。

+ VHD を Azure にアップロードするか、リージョン間でディスクをコピーする - Azure PowerShell - Azure Virtual Machines | Microsoft Learn

https://learn.microsoft.com/ja-jp/azure/virtual-machines/windows/disks-upload-vhd-to-managed-disk-powershell#manual-upload

## コマンド概略
主に CLI 操作が必要なターゲット環境側での操作です。
```powershell:Azure PowerShell
#空のマネージドディスクの作成
# サイズは 8TiB=8192 GiB (8796093022208 バイト) + 512 バイト = 8796093022720 バイト で計算
$diskconfig = New-AzDiskConfig -SkuName 'Standard_LRS' -OsType 'Windows' -UploadSizeInBytes '8796093022720' -Location '<yourregion>' -CreateOption 'Upload'
New-AzDisk -ResourceGroupName '<yourresourcegroupname>' -DiskName '<yourdiskname>' -Disk $diskconfig

 # sas の発行
$diskSas = Grant-AzDiskAccess -ResourceGroupName '<yourresourcegroupname>' -DiskName '<yourdiskname>' -DurationInSecond 864000 -Access 'Write'
$disk = Get-AzDisk -ResourceGroupName '<yourresourcegroupname>' -DiskName '<yourdiskname>'
 
# ソース URL は スナップショットのエクスポートから発行した SAS 付き URL
AzCopy.exe copy '<ソース sas>' $diskSas.AccessSAS --blob-type PageBlob

# sas の無効化 
Revoke-AzDiskAccess -ResourceGroupName '<yourresourcegroupname>' -DiskName '<yourdiskname>'
```

上記はデータディスクのコピー際のコマンドです。OS ディスクの際は オプションが必要になります。

:::note info
> OS ディスクを作成する場合は、-HyperVGeneration '<yourGeneration>' を New-AzDiskConfig に追加します。

https://learn.microsoft.com/ja-jp/azure/virtual-machines/windows/disks-upload-vhd-to-managed-disk-powershell#copy-a-managed-disk
:::


## 手順詳細
*後述の手順で出てくる SAS は執筆時時点で使えない状態となっています。

今回の環境
+ ソース環境
Subscription ID：XXXXXXXX-XXXXX-XXXX-XXXXXXXXe83
リソースグループ：RG-azcopy
ディスク：empty-8192Gib
スナップショット：snapshot-8192Gib
	
	
- ターゲット環境
Subscription ID：XXXXXXXX-XXXXX-XXXX-XXXXXXXX40a
リソースグループ：RG-SAS-test
作成する予定のマネージドディスク：re8TiBDisk


###  ターゲット環境に空のマネージドディスクを作成(書き込みSAS Upload 可能な状態で作成)
Cloud Shell か、ローカルにインストールした Azure PowerShell でターゲット環境で以下のコマンドを実行する。

```PowerShell
# VHD サイズを指定
$vhdSizeBytes =8796093022720
 
# サイズは 8TiB=8192 GiB (8796093022208 バイト) + 512 バイト = 8796093022720 バイト で計算
$diskconfig = New-AzDiskConfig -SkuName 'Standard_LRS' -OsType 'Windows' -UploadSizeInBytes '8796093022720' -Location 'japaneast' -CreateOption 'Upload'

#マネージドディスクの作成
New-AzDisk -ResourceGroupName 'RG-SAS-test' -DiskName 're8TiBDisk' -Disk $diskconfig
```

::: note
8 TiB の場合の計算
$vhdSizeBytes =8796093022720
(計算式 8(TiB)×1024^4=8796093022208 バイト,
8796093022208 バイト+512バイト＝8796093022720 )
:::


例：
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2982508/b5969f0d-8419-246f-0724-3d9dc9a65428.png)

```PowerShell：Azure PowerShell
# SAS の発行
$diskSas = Grant-AzDiskAccess -ResourceGroupName 'RG-SAS-test' -DiskName 're8TiBDisk' -DurationInSecond 864000 -Access 'Write'
$disk = Get-AzDisk -ResourceGroupName 'RG-SAS-test' -DiskName 're8TiBDisk'
# SAS の確認
$diskSas.AccessSAS
```
ディスクの状態が **"Active Upload"** となっていることが確認できる。

:::note
+ ReadyToUpload : ディスクはアップロードを受け取る準備ができていますが、Secure Access Signature (SAS) が生成されていないことを意味します。
+ ActiveUpload : ディスクはアップロードを受け取る準備ができており、SAS が生成済みであることを意味します。
ref: https://learn.microsoft.com/ja-jp/azure/virtual-machines/windows/disks-upload-vhd-to-managed-disk-powershell

また、SAS の有効期限が切れた場合。「ReadyToUpload 」 → 「ActiveUpload 」へと状態が遷移します。後述しますが、 **SAS の有効期限は長めに設定するのがよしです。**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2982508/823cc087-360e-4ae8-5126-dab316184334.png)

:::

例：
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2982508/71c78740-25d5-0bf4-d96d-f125d97777f6.png)


>$diskSas.AccessSAS
https://md-impexp-x0nqdqpkgpsw.z15.blob.storage.azure.net/3kq5qpk1t3nc/abcd?sv=2018-03-28&sr=b&si=19a9ac75-a6d5-4efe-876e-45527d53ecfb&sig=s7OiIyEz1OABNxeYJStPl3C%2B7JrmZM0wf9C9qxVXCKI%3D


::: note
```$diskSas.AccessSAS``` が Azcopy の際に必要なので必要に応じてメモしておきます。
こちらが後ほど ```azcopy copy ‘<ソース SAS>’ ‘<ターゲットSAS>’``` の ```<ターゲット SAS>’``` になります。
:::

### ソース環境のスナップショットの SAS を発行

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2982508/7a69d002-c6be-3eb2-c4af-de03ccc5c6e7.png)

> ソースのスナップショットの SAS
https://md-sqx33tdmdh33.z2.blob.storage.azure.net/gv0whkrltqnk/abcd?sv=2018-03-28&sr=b&si=8ffba7f2-e30e-4fa6-9565-3990fa86db8b&sig=sgzgpnpOS3JLWZaIRcsL%2Fw92S1eIOiXzy12Sr%2Fh6FNc%3D

::: note
```$diskSas.AccessSAS``` が Azcopy の際に必要なので必要に応じてメモしておきます。
こちらが後ほど ```azcopy copy ‘<ソース SAS>’ ‘<ターゲットSAS>’``` の ```’<ソース SAS>’``` になります。
:::


### Azcopy の実行 
```powershell:Azure PowerShell
$SSAS="(先ほど発行したソースのスナップショットのSAS)"
$DSAS="(先ほど発行したターゲットのマネージドディスクのSAS = $diskSas.AccessSAS)"]
 azcopy copy "<ソース SAS>" "<ターゲットSAS>"
```
例：Cloud Shell
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2982508/03869f3e-5f76-9b2b-de1d-76195515bf12.png)
例：ローカル PowerShell (参考)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2982508/b33795cd-e63b-e3cc-3de6-a6ee2f53146e.png)


### SAS を無効にする
+ ターゲット環境側
```
# sas の無効化 
Revoke-AzDiskAccess -ResourceGroupName '<yourresourcegroupname>' -DiskName '<yourdiskname>'
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2982508/bdf1843e-811f-5a47-98d6-d53ec9aa6b11.png)

:::note warn
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2982508/240d9ae2-405d-8a58-2be0-3ea3de83e740.png)
SAS の有効期限が切れ (「**ReadyToUpload** 」 → 「**ActiveUpload**」となった状態) て、その間に azcopy が終わらなかった場合では下記のようにError Messageが出てしまうので、**SAS の有効期限は長めにしておくのがよし。**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2982508/96289ce4-f891-3d92-f7e8-fd09c50430e8.png)
ちなみに、 **ReadyToUpload** 状態で SAS を失効させようとすると以下のような、Error Message がでます。

```
Revoke-AzDiskAccess: The specified cookie value in VHD footer indicates that disk 'abcd' with blob https://md-impexp-p3zm11jwdzwz.z27.blob.storage.azure.net:8443/mh3cxx5wbmhx/abcd is not a supported VHD. Disk is expected to have cookie value 'conectix'.
ErrorCode: InvalidVhd
ErrorMessage: The specified cookie value in VHD footer indicates that disk 'abcd' with blob https://md-impexp-p3zm11jwdzwz.z27.blob.storage.azure.net:8443/mh3cxx5wbmhx/abcd is not a supported VHD. Disk is expected to have cookie value 'conectix'.
ErrorTarget: 
StatusCode: 400
ReasonPhrase: Bad Request
OperationID : e9a2ccbb-957f-47cd-8561-5eed195f1a27
```


:::

:::note warn
また クラウドシェルではセッションタイムアウトの時間があり、セッションタイムアウトが発生すると azcopy が実行中にセッションタイムアウトする可能性があるので、今回のように大きいサイズの Azcopy を実行する際はローカル OS 上 から Azcopy を実施することをオススメします。
+ Azure Cloud Shell に関してよくあるご質問 (FAQ) | Microsoft Learn
https://learn.microsoft.com/ja-jp/azure/cloud-shell/faq-troubleshooting#is-there-a-time-limit-for-cloud-shell-sessions
> Cloud Shell は対話型のユース ケースを想定しています。 Cloud Shell セッションは、無操作状態で 20 分経過するとタイムアウトとなります。 そのため、実行時間の長い非対話型セッションは、警告なしで終了します。

ただし、ローカル端末から Azcopy を実施すると以下のエラーが発生する可能性があります。

```
panic: runtime error: invalid memory address or nil pointer dereference
[signal 0xc0000005 code=0x0 addr=0x0 pc=0xc063ea]
```
 ![2024-03-26_06h27_50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2982508/2e648fde-b840-7366-7bf6-a58cdc0f2663.png)


検証した結果、 **<font color="red">Azcopy 10.23.0</font> では上記のエラーが発生するが、<font color="red">Azcopy 10.20.0</font> では起きない**ことが確認できました。
 もし、どうようのエラーがでた場合は一度、Azcopy のバージョンを変えて試してみてください
+ Azcopy 10.20.0 のダウンロードリンク：[https://azcopyvnext.azureedge.net/releases/release-10.20.0-20230727/azcopy_windows_amd64_10.20.0.zip](https://azcopyvnext.azureedge.net/releases/release-10.20.0-20230727/azcopy_windows_amd64_10.20.0.zip
)

:::


:::
+ ソース環境側
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2982508/4a355585-4036-7853-3cca-e80ba0ea4bd5.png)

# 他の方法
以下の方法でも可能です。
+ Azure Storage Explorer を用いてディスクをコピー
Azure Storage Explorer でも下記ブログ記事に記載の手順にて、8192 GiB マネージド ディスクのコピーが可能でした
 
・Azure Storage Explorer を用いて、コマンド無しで VM を別のリージョン・サブスクリプション・テナントに移動/複製をしてみよう | Japan Azure IaaS Core Support Blog

https://jpaztech.github.io/blog/vm/copy-vm-with-storage-explorer/

+ Azure Storage Explorer とは

https://azure.microsoft.com/ja-jp/products/storage/storage-explorer/