新しもの好きプログラマの耳より情報ブログ

仕事でもあるプログラミングについて役に立ちそうな情報を発信していこうというブログです。役に立たなそうな情報はfacebookで。

AzureでWindowsアプリのCI/CD環境を作る:DevDriveを組み合わせてみる

概要

開発者の手元のビルド環境だけではなく、どこでもリリースビルドが再現可能であること。 Warningの作り込みやUTコードのFailを早めに見つけてデグレを防ぐこと。 こうした、CI/CD的な考え方は、Windowsアプリ開発においても大事なところだと思います。(現場であまり重視されていない感もありますが・・・)

方法はいくつもあると思いますが、Azure Pipelines (DevOps)とAzure VMで実現できます。そのあたりの話はまた別の記事で書こうと思います。

この記事の話は

Windows 11の新機能として登場したDevHomeやDevDriveなどは、もちろん開発環境の量産にも使えますが、実はCI/CDを大きく助けてくれる機能にもなりそうです。

今回は、その中でもDevDriveが導入できるかを試してみて、効果を見ていこうと思います。

結果まとめ

説明が長くなるので、最初に結果をまとめます。こんな感じの内容を説明していきます。

  1. Azure Pipelinesのビルド環境にDevDriveを組み込むこと自体は難しくない
  2. むしろWin11-23H2へのDevDriveの導入で、Defenderのアップデートが必要なのが罠だった
  3. 中でも、一時ディスクDドライブにコマンドで作成する方法が、低コストで使いやすいと思ったので、それを紹介
  4. 効果はいまいちで、ビルド時間が数%減るか減らないかくらい
  5. むしろCPU強化のほうが効果があったので、そのあたりがネックにならないリッチなビルド環境向けかも
  6. 少なくともマイナスではなかったので、ダメ元で導入してみても良いと思う

環境の作り方

Azure Pipelinesのビルド環境にDevDriveを組み込む方法について、注意点なども触れながら順番に紹介します。

DevDriveの導入

DevDriveは、ディスク上のパーティションを割り当てるか、もしくはvhdファイルを新規作成してDevDriveにするという作り方をします。注意点として、最低サイズが50GBです。50GB以上の空きパーティションか空き領域があれば、作成できるということになります。

とりあえず導入するための手順であれば、MSのドキュメントがちゃんとまとまっていますので、そちらを見るのが良いです。

Windows 11 で Dev Drive を設定する | Microsoft Learn

DevDriveのウイルススキャンの影響を減らす

DevDriveのパフォーマンスが高いとされる理由の一つに、Defenderのウイルススキャンの影響を減らせるという点があります。「パフォーマンスモード」と呼ばれているようですが、ウイルススキャンを遅延させることで速度を上げるようです。これを使わないと、DevDriveのメリットは半減以下です。

幸い、DevDriveを作るだけで、デフォルトでパフォーマンスモードの対象になりました。この点は分かりやすいです。

意外な注意点

Defenderのアップデートが必要です。

Windows11 23H2を新規インストールすると、Defenderのバージョンが古くて、DevDriveパフォーマンスモードの条件を満たしません。2023/12前半時点では、2回くらい手動でアップデートを促してやらないと、条件を満たすバージョンになりませんでした。見た目にはDevDriveになっているので気付きづらく、今のところ注意が必要です。

参考:パフォーマンス モードを使用して Dev Drive を保護する | Microsoft Learn

DevDriveとAzure Pipelinesの組み合わせ方

まず、Azure PipelinesのSelf Hosted Agent(長いので、以下Agent)でビルドする時は、こんな感じになります。

この「ローカルの一時フォルダ」を、DevDriveにすれば良いことになります。幸い、Agentはセットアップする時に一時フォルダの場所をフルパスで指定できます。パスが存在していなくてもAgentは起動できるので、あとからDevDriveを作成・マウントしても問題ないので、このあとに出てくる一時ディスクを使えます。

Azure VMの一時ディスクがお勧め

Azure VMには、OSディスクとデータディスクの他に、一時ディスクというものがあります。名前の通りでVM停止時などにデータが失われる可能性がありますが、必ずOSと同じハードに物理接続されているディスクであり、元々ページファイルなどを置く想定のディスクなので速度が期待できます。また、VMの料金に含まれています。

この特性は、一時的に使うだけのビルドPCの用途にはぴったりです。ただし、データが失われた場合はDevDriveを作り直す必要があります。これを毎回手動でやるのは厳しいですが・・・スクリプトで実現できました。次にそのやり方をまとめます。

一時ディスク上のDevDriveを使った、ビルド環境の運用方法

ここまでの内容を踏まえて、次のようにビルド環境を構築・運用できます。

  1. Agentをセットアップして、一時フォルダのパスを存在しないドライブにしておく(「V:\AgentWork」など)
  2. 「一時ディスク(Dドライブ)へvhdファイルを作成・マウントしてDevDriveに設定し、1で設定したドライブレターを与える」というスクリプトを作成し、タスクスケジューラの「スタートアップ時」イベントに登録する

これで、VMを起動するだけで使える、DevDriveでのビルド環境のできあがりです。次の図のようなものが実現できました。

スクリプトについては、DevDriveの設定はFormatコマンドで行えるので、DiskPartと組み合わせて次のバッチファイルで行けます。

https://gist.github.com/suusanex/67610d6d8a7cfd7abca6e0e3108507d8

効果は?

色々試しましたが、少しは速くなるもののあまり効果はない印象です。続けて詳しく書いて行きます。

効果の測定

測定のやり方

次の条件で、実際にパイプラインを動かして所要時間を測定していきます。

  • 測定対象
    • 1,C#C++(WDK)の小規模ソリューション(非公開・手元にあったもの)
    • C#部分は発行(publish)、WDK部分はビルド
    • 2,OrchardCore
    • MSのブログで、DevDriveのパフォーマンス例で22%改善としていたもの
    • VisualStudio2022で、ソリューション構成Release/Any CPUをビルド
  • 測定条件(組み合わせて測定する)
    • VMのサイズ
      • Standard_D4ds_v5
      • Standard_F8s_v2
    • ストレージ
      • 一時ディスク(Dドライブ)
      • データディスク Premium SSD
    • DevDrive
      • パーティション全体をDevDriveに設定(Premium SSDのみ)
      • vhdファイルを作成してマウントし、DevDriveに設定(一時ディスクのみ)
      • DevDrive無し(通常のNTFS
  • 測定方法
    • 2~3回ほどパイプラインを実行して、パイプライン実行結果に記録された所要時間を見る
      • 対象条件での初回の実行結果は捨て、2回目以降の実行結果を採用する
      • あまり効果が見られないため、途中から一部組み合わせの測定をカットしたり回数を減らしたりしている

測定結果

条件別に、次の対象の測定結果を表にまとめます。測定結果の単位は全て秒です。

  • 対象1:測定対象1のcheckout
  • 対象2:測定対象1のC#ソリューション発行
  • 対象3:測定対象1のWDKビルド
  • 対象4:測定対象2のNuGet復元
  • 対象5:測定対象2のソリューションビルド

Azure VM Standard_D4ds_v5

データディスクでは、ほとんど差が無いという印象です。一時ディスクのほうでは、数%くらいはDevDriveのほうが優れてるかも・・・?というところでしょうか。動きを見ているとCPUが一番ネックになっていそうにも見えるので、CPUが強そうなサイズに変えてみます。

ストレージ 対象1 対象2 対象3 対象4 対象5
データディスク NTFS 8~20 53~61 10 19~20 98~108
データディスク DevDrive 7~12 53~60 10~11 19~23 103~111
一時ディスク NTFS 10~19 57~62 11~13 - -
一時ディスク DevDrive 7~10 54~58 10 - -

Azure VM Standard_F8s_v2

もう少し効果が明確になった印象でしょうか。せいぜい5%がいいところですが、確かに改善はしているように見えます。もしかして、IOPS制限などAzure VM固有の要素に影響されているのかもしれないので、ローカルのHyper-Vも試してみます。

ストレージ 対象1 対象2 対象3 対象4 対象5
データディスク NTFS 9 78 13 24 85~100
データディスク DevDrive 9~11 68~75 13 24~27 91~95
一時ディスク NTFS - - - 25~28 92~100
一時ディスク DevDrive 15 73 13 24~26 84~95

Hyper-V(あまり性能は良くない)

適当に確保したローカルのHyper-V環境での測定です。さほど性能が良いものではありません。こちらでは10%程度の改善はしているように見えます。Azure VM固有の要因が悪いと言えるほどのデータではありませんが、条件によっては改善幅が大きくなるものと期待はできます。

ストレージ 対象1 対象2 対象3 対象4 対象5
システムドライブ NTFS - - - 22~24 100~112
システムドライブ上のvhd DevDrive - - - 24~28 89~108

考察

MSのブログで出ているような22%もの改善は得られませんでした。とはいえ、ストレージが大きなネックになっている環境では、5~10%程度の改善は出ているように見えます。当たり前といえばそうですが、ストレージ以外がネックになっている場合は効果は出づらいようです。もしかするとDevDriveは、もっと各種スペックが高くてストレージだけがどうしてもネックになる、というようなリッチなビルド環境でこそ力を発揮するのかもしれません。

いずれにしても、「DevDriveにしたら、かえって悪化した」ということはなく、使って損はないようです。

Azure VMにおいては、高価なPremium SSDを使っても一時ディスクと速度に大差はありませんでした。追加コストを支払ってデータディスクを追加するよりも、一時ディスクを使うほうが良さそうです。

まとめ

Azure VM&Azure Pipelinesを使ったビルド環境に、DevDriveを組み込むことができました。 また、スクリプトで自動作成することで、Azure VMの一時ディスク上へDevDriveを作ることができるので、現状のVMのサイズによっては追加のコスト負担無しで使うことができます。

DevDriveを使用した場合には、22%という大きな改善効果こそ見られなかったものの、使って損はない程度の改善は見られました。一時ディスク上に確保してとりあえず使ってみる価値はあるように思います。色々な条件に左右されるので、もしかして用途によっては大きな改善を得られるかもしれません。