AzureRMスクリプトを簡単にアップグレードする

# はじめに
今回は2024年2月29日にリタイアメントを迎える「AzureRM」のアップグレードの話を書きます。

Azureでシステム構築・運用する際に、PowerShellモジュールをインストールし、スクリプトを開発するシーンがあります。私が担当しているプロジェクトでも運用系や自動構築系のスクリプトを数多く作成しています。

Azure関連のPowerShellで、古くから利用されてきたのが「AzureRM」モジュールですが、この「AzureRM」モジュールは2024年2月29日にリタイアとなることが決まっており、現在では（というか3~4年前からですが）「Az」モジュールという新しいバージョンのモジュールを利用することになります。

比較的新しいプロジェクトではすでに「Az」モジュールを使われていると思いますが、未だに「AzureRM」モジュールを使っているプロジェクトでは、「AzureRM」前提で書かれているスクリプトに対するアップグレード作業を行う必要があります。


# アップグレードの方法
AzureRMとAzの各コマンドは基本的な構文は同じですので、”AzureRm”の部分を”Az”と書き換えるのが基本的なパタンです。
例えば、__Get-AzureRmVM__ コマンドにであれば、__Get-AzVM__ と書き換えればOKです。ただ「ホントに全てのコマンドを同様のルールで単純置換していいの？」や「モジュールバージョンが違うので実は引数変わってない？」といった不安が残ります。実際この置換ルールに則っていないコマンドも存在していますし、全てのコマンドについて網羅的に調査するのは本当に骨が折れる作業になります。

さて、こんな時役に立つのが、__Az 移行ツールキット__ です。このツールはMicrosoftの移行ガイドでも紹介されているツールでAzureRM→Azにアップグレードする際のチェックと実際の移行（置換）を行ってくれるツールです。

https://learn.microsoft.com/ja-jp/powershell/azure/migrate-from-azurerm-to-az?view=azps-9.6.0&viewFallbackFrom=azps-6.2.1

# 「Az 移行ツールキット」使ってみた
導入手順はAzureRMモジュールやAzモジュールの導入方法と同じやり方になります（Install-Moduleを実行）。ただ、その前に下記のコマンドを実行し、AzureRMモジュールが最新の” 6.13.2”になっているかを確認してください。
```PowerShell
Get-Module -Name AzureRM -ListAvailable -All
```
こんな感じでバージョンを確認することができます。ここではすでに”6.13.2”になっていますが、もし古いAzureRmモジュールがインストールされている場合は最新バージョンを入れましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1199489/e44d110b-cd85-f199-56fe-5564f7dc20a9.png)

続いて、下記のコマンドを実行し、Az移行ツールキットをインストールします。
```PowerShell
Install-Module -Name Az.Tools.Migration
```

導入手順はこれだけです。

## アップグレード可否チェック
無事インストールが完了したら、__New-AzUpgradeModulePlan__ コマンドを実行し「アップグレードプラン」を作成します。現在のMSサイトのサンプルでは、移行後のAzバージョン指定が"8.0.0"となっていますが、現在は対応していないため __"9.3.0"__ 以降のバージョンを指定します。

```PowerShell
New-AzUpgradeModulePlan -FromAzureRmVersion 6.13.1 -ToAzVersion 9.3.0 -DirectoryPath '<スクリプト格納パス>' -OutVariable <プラン名>
```

すると、下記のようにスクリプト内のAzureRMコマンドに対する移行可否をチェックをしてくれます。よくよく見ると、AzureRmコマンド以外に、AzureStorage系などもチェックしてくれていました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1199489/19c41aac-8966-3cfe-5c63-b3afeb92a422.png)

ステータスがOK（ReadyToUpgrade）でない箇所については下記のコマンドで抽出することができます。（先のコマンドの「-OutVariable」（上記の例では”Plan”）が結果を格納するオブジェクトになっています。

```PowerShell
$Plan | Where-Object PlanResult -ne ReadyToUpgrade | Format-List
```

今回のチェックでは、300程が対象で、その内ワーニングが出たのは2箇所ですがいずれも同じ理由でした。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1199489/05c96071-8029-2a64-b1e1-bd224243529b.png)

__ワーニング内容__
__Parameter was not found in New-AzResourceGroupDeployment or its aliases, but this may not be a problem because this cmdlet also supports dynamic parameters.__

こちらのワーニングは引数にPowerShellの __動的パラメータ__ という機能を使ったもので、本来のAPIが持っていない引数になります。そのため、チェック結果としては警告扱いになっていますが、実際はおそらく問題ないものとなります。（メッセージもそういう内容ですね。）

今回の対象スクリプトでは出ませんでしたが、MSサイトによると、エラーとなる場合は下記のメッセージがでるそうです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1199489/147ca893-3db3-d74a-4c27-f430e79bb750.png)

## アップグレード実行
チェックが終了し、プランに問題はなかったため、__Invoke-AzUpgradeModulePlan__ コマンドを実行して実際にアップグレードをしてみます。「-FileEditMode」引数に「SaveChangesToNewFiles」をしてすると、オリジナルのスクリプトをコピーした上でアップグレードが実行されます。
__※「-FileEditMode」引数に「ModifyExistingModulePlan」を指定するとオリジナルのスクリプトを上書きしてしまうので注意してください！__

```PowerShell
Invoke-AzUpgradeModulePlan -Plan $Plan -FileEditMode SaveChangesToNewFiles -OutVariable Results
```
すると、アップグレードが実行され、結果が出力されました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1199489/97741299-8455-849c-00cb-30b495c4b4bf.png)

アップグレードされたスクリプトはオリジナルのスクリプト名に「_az_upgraded」が付いています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1199489/4d034b47-8e51-e424-2bba-8f71fe2a286f.png)

念のためDIFFを取ってみるときちんと変わっていることが確認できました！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1199489/a268a997-8fc6-a867-8332-cedee95d2ce9.png)

一応MSサイトに書いてる制限事項も挙げておきます。

* ファイル I/O 操作では、既定のエンコードが使用されます。 通常とは異なるファイル エンコードの場合は、問題が発生する可能性があります。
* Pester 単体テストのモック ステートメントに引数として渡される AzureRM コマンドレットは、検出されません。

## アップグレードが終わったら・・
スクリプトのアップグレード作業自体は「Az移行ツールキット」にお任せできることがわかりました。あとは、この後待ち受けているのは大量のノンデグレードテストです。当然テストは必要ですので、その分の工数はちゃんと積んでおきましょう。その他、詳細設計書を作っている場合は、ドキュメント修正も発生します。そしてAPI実行基盤サーバみたいな実行環境を用意している場合は、その環境自体のAzモジュール化作業も必要になりますので、漏れなく工数に積むようにしましょう。

# おわりに
今回は、AzureRMモジュールのリアイアメントに伴い、簡単にアップグレードする方法をまとめてみました。現時点でこの内容でお困りの方は少ないかもしれませんが（私だけ？？）、ご参考になれば幸いです。