Azure Virtual Desktop (AVD)のリファレンスアーキテクチャとARMテンプレート

GitHubに"[Azure Virtual Desktop Reference Architecture](https://github.com/takeokams/wvd-reference-architecture)"を公開したので、その使い方です。GitHubの方がオリジナルで、こちらの記事はサブテキストです。
なお、Azure Virtual Desktopの旧称であるWindows Virtual Desktop (WVD)も使われていますが、機能に差異はないため、単純にAVDに読み替えてください。

# リファレンスアーキテクチャ / 構成図
![wvd-ra.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/684720/23eac44d-d9c7-5e3f-7ec2-5b04a8fcedc5.png)
### 特徴
- ネットワークはハブ & スポーク アーキテクチャ
- インターネットに直接VMを公開しない; 管理、緊急時にはBastionを利用
- インターネットアクセスはオンプレミスに引き込まず、Azure上でブレークアウトさせる; Azure Firewall Premiumを使って柔軟で詳細なアクセスコントロール
- 高可用性を考慮; Availability Zone、マネージドサービスを利用
- ログの集中管理; Azure Monitorブックで可視化

# これはなに?
- 本番想定の構成でAzure上に環境を作るもの
- ここから個別の本番環境に発展させられる
- Preview機能を柔軟に取り入れられ、本番想定環境でその有効性を確認できる
- ARMテンプレート、PowerShellスクリプトがあるので、サクッと使える、何度も使える

Azureに慣れておられる方なら、[クイックスタートテンプレート](https://azure.microsoft.com/ja-jp/resources/templates/)のような位置づけでとらえていただけるとわかりやすいです。
他の形のアーキテクチャデザインもありますが、典型的な一つのデザインです。

# GitHubにあるもの
"[Azure Virtual Desktop Reference Architecture](https://github.com/takeokams/wvd-reference-architecture)"には、アーキテクチャにあるコンポーネントをデプロイするための、ARMテンプレートやPowerShellスクリプト、また必要に応じてGUI操作の手順が書かれてあります。
本番環境では、ADは既存のオンプレミスと接続したい、とか、ファイルストレージはパフォーマンスの観点からAzure NetApp Filesを利用したい、などあると思いますので、大分類でパートを分けてデプロイできるようにしてあります。
逆にないものとして、AVDのホストプールはこのGitHubでは公開していません。これは、マルチセッション、シングルセッション、VMの中のアプリ構成など利用者環境によってさまざまなためです。すぐ使いたければ、Azureのギャラリーイメージを使えば数分で環境はできてしまいます。

# デプロイの流れ
3つのパートに分けていて、それぞれのパートを実施することで、リファレンスアーキテクチャに近づけていきます。

1. ネットワークインフラ
2. Active Directory
3. FSLogixのプロファイルを置くストレージ

ここから、各パートの解説です。

## ネットワークインフラ
![wvd-ra-network.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/684720/bed92f46-6547-d3f7-48dd-fd42e5df0d7a.png)
[ハブ アンド スポーク ネットワーク トポロジ](https://docs.microsoft.com/ja-jp/azure/cloud-adoption-framework/ready/azure-best-practices/hub-spoke-network-topology)でネットワークインフラを構成します。
オンプレミスとの接続は、S2SのVPNやExpressRouteなどの形態もあれば、それぞれ接続情報が違いますので、個別の設定が必要です。S2Sの仮想ネットワークゲートウェイをテンプレート内でデプロイすることも可能ですが、これはサンプルです。
次のパートのActive Directoryのテンプレートを使う場合、Availability Zoneに依存しているため、西日本ではなく東日本でデプロイする必要があります。
![network-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/684720/cec98dfa-0a4a-e71c-25b0-61ee3b1eee26.png)
`Windows VM Count`は`1`にすることをお勧めします。これを指定することでスポークネットワークにWindows VMを1台作成するのですが、このVMをネットワークの疎通テストなどに使えるためです。このWindowsのユーザーが、`Admin User Name`と`Admin Password`です。これ以外にこのユーザー情報は使われません。
赤囲み以外も変更することが可能です。オンプレミスと接続する場合は、オンプレミスのネットワークレンジと重ならないように変更してください。

## Active Directory
![wvd-ra-ad.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/684720/5a82690e-307a-8860-90bd-ed937a1e635d.png)
ハブネットワークの中に、Active Directoryを立ち上げて、AVDホストの認証をここで行います。
GitHubで公開しているARMテンプレートは、ドメインコントローラが構成された2台のVMをAvailability Zoneで分けて展開します。
![activedirectory-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/684720/9f9f3078-17e9-b8db-cd0a-8a962dce9bac.png)
先ほどのネットワークインフラの作成でネットワークレンジを変更した場合は、赤囲み外のIPアドレスも変更する必要があります。
`Ip Address`に2つIPアドレスがありますが、前者はPDC、後者はBDCです。

### 追加手順
ARMテンプレートでの展開が終わったら、以下の作業を行います。
#### Azure AD Connect
PDCにBastion経由で接続します。
![ad-connect-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/684720/88bffb14-1ada-a6ef-17ce-e2fe4f6a70a6.png)
デスクトップにAzure AD Connectのインストーラーのアイコンがあるので、ここから起動し、ウィザードに従って、express settingsで設定します。なお、TLS 1.2の指示が出る場合は、画面の指示に従ってDocsを参照し、TLS 1.2を有効にしてから再度実行します。
![ad-connect-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/684720/b267ff3a-62e9-009d-730c-cfbb1b1d253b.png)

#### DNS
ADDSで名前解決できるように、ネットワークインフラを設定します。

- ハブネットワーク
![dns-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/684720/d1185348-be34-5510-06e6-6839b6560982.png)
ここでは、PDC, BDCのIPアドレスを指定します。

- ファイアウォールポリシー
![dns-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/684720/0d9a9d25-41a6-f03f-eb59-1cba15a9e92f.png)
ここでは、PDC, BDCのIPアドレスを指定するとともに、ファイアウォール自身がDNSのプロキシになるように設定します。


- スポークネットワーク
![dns-3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/684720/d1ed1714-c73d-1781-3642-bb80370e1c0e.png)
ファイアウォールのプライベートIPアドレスを指定して、DNSの名前解決をファイアウォールに向けます。
スポークネットワークは2つ作っていますので、両方に設定します。

#### TLS Inspectionのための証明書
ネットワークインフラのARMテンプレートでは仮の証明書が設定されているので、Active Directory Certificate Services(ADCS)のEnterprise CAに署名された証明書を、Azure Firewall Premiumにセットします。
ADCSはPDCにインストールされていて、Enterprise CAが構築されています。このため、Enterprise CAの証明書は、ドメイン参加したWindowsクライアントには自動的に信頼された証明機関として配布されます。

- キーコンテナ (Key Vault)へのアクセス権設定
![cert-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/684720/b9d8651a-9f73-a6d9-4aa7-0a37f192c153.png)
![cert-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/684720/ec2ec7fb-2c6c-fe89-2a34-2f2a0dcb9db2.png)
![cert-3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/684720/566ec08b-4773-7dc2-4ff1-ba2263644a42.png)
![cert-4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/684720/2e35bd28-ab31-6cef-97e0-ff8894525999.png)
![cert-5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/684720/26217a1f-5d03-d419-6f7a-04a4e63373e0.png)

- 証明書リクエストの作成
![cert-6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/684720/84ca96b5-9101-a41b-5c85-200e8b0d1b1b.png)
![cert-7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/684720/2e3bd1c4-55b3-f2d5-5cd5-04f4c001454e.png)
証明書の名前と件名(Subject Name, Common Name)は、組織で適当なものを設定します。
![cert-8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/684720/5baf63cf-71fe-605c-10b9-4e1a324432a8.png)
作ったものをクリックして開きます。
![cert-9.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/684720/ded18dd5-1c0c-c53d-00e4-bcd052a5ae54.png)
![cert-10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/684720/5a8727c4-0a75-3a10-76f4-757336f59fd7.png)

- Enterprise Root CAで署名し証明書を作成
PDCのVM内で操作します。
![cert-11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/684720/2afe1254-3a0a-a0cf-65c2-1fa153a7d8dd.png)
![cert-12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/684720/8fe5c8b5-5c13-afe1-b3cb-7386df1ce51d.png)
IEから`http://localhost/certsrv`に接続します。
![cert-13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/684720/201da909-68b3-4b9d-d410-6a490a594008.png)
![cert-14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/684720/69d13aa9-36b2-aee3-1d8a-6b7ee16e2827.png)
![cert-15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/684720/59c1078e-6aca-4418-349b-92be632142d4.png)
ダウンロードしてある証明書リクエスト(CSRファイル)をメモ帳で開き、その内容をコピペし、発行する証明書タイプを指定してから、Submitして署名を行います。
![cert-16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/684720/9324450a-7bea-2603-a38f-7110a4d38201.png)
![cert-17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/684720/42233227-9ba9-5893-6886-751dbfc0b3f5.png)

- 署名された証明書の登録
![cert-18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/684720/c3f974c3-c8d2-0772-1004-104504473973.png)

- ファイアウォールポリシーの証明書の入れ替え
![cert-19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/684720/0b29f105-5b28-a6d4-2a3f-e90c5185879c.png)

## FSLogixのプロファイルを置くストレージ
![wvd-ra-storage.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/684720/d04b7033-9934-f3de-383b-fa42b9b57a6a.png)
上のダイアグラムで、一番右にあるものです。
ユーザー視点でAVDで利用するVMが接続するたびに切り替わっても、同じ設定のWindowsが使えるようにするため、プロファイルをVMから切り離して置く場所になります。FSLogixの仕組みを使います。これにはBLOBストレージなども使えますが、パフォーマンス上の観点から、Azure Files以上のものが推奨されます。
複数のユーザーが同時にログインするような環境ではアクセスが集中します。これを`ログインストーム`と呼ぶのですが、このような環境ではユーザーの認証が終わってからデスクトップが開くまでに時間がかかることがあり、Azure FilesからAzure NetApp Filesに切り替えたり、ストレージを分散したりするのが一般的です。進め方としては、このアーキテクチャのまま新しいストレージを横付けし、プロファイルへのUNCパスを変更してパフォーマンスの差分計測をするのがよいと思います。
なお、`ログインストーム`によるパフォーマンス影響は、このストレージだけでなく、VMやマルチセッションであれば集約率にも依存していますので、[docsのガイド](https://docs.microsoft.com/en-us/windows-server/remote/remote-desktop-services/virtual-machine-recs)も設計時に参考にできます。

![storage-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/684720/fbef645d-491d-4609-7ba7-e2891aaba71e.png)
`Storage Account Name`には、Azure全体の中でユニーク(他で使われていない)なものを指定する必要があります。ストレージアカウント作成のブレードを出して事前に確認しておくのがおすすめです。
![storage-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/684720/aa90bf45-3e64-2fec-697f-8f4c59873c16.png)
※ このブレードでは利用できるかどうか確認するだけです。作成はARMテンプレートで行います。

### 追加設定
「[Microsoft Cloud Workshop: エンタープライズでの Windows Virtual Desktop の実装](https://github.com/takeokams/MCW-Implementing-Windows-Virtual-Desktop-in-the-enterprise/blob/main/Hands-on%20lab/HOL%20step-by-step%20-%20Implementing%20Windows%20Virtual%20Desktop%20in%20the%20enterprise.md#%E6%BC%94%E7%BF%92-3-fslogix-%E7%94%A8%E3%81%AE-azure-%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E5%85%B1%E6%9C%89%E3%81%AE%E4%BD%9C%E6%88%90)」をベースに設定していきます。
[GitHubの説明](https://github.com/takeokams/wvd-reference-architecture#%E5%90%84%E7%A8%AE%E8%A8%AD%E5%AE%9A-1)では、このワークショップの記事にある内容をPowerShellスクリプトにしてあるので、PDCのVM内でPowerShell ISEを管理者モードで開き、そこにコピペして、必要な変数の値を変更して実行すれば問題ないでしょう。

#### ストレージアカウントへのアクセス設定
最後の手順に、ストレージアカウントへのアクセス設定がありますので、画面を掲載しておきます。
![storage-3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/684720/3e9d801d-35c2-a643-aa16-5afea5cb1d62.png)
スポークネットワークにあるホストからのパケットは、ファイアウォールにルーティングされる設定がされているため、ルールがなければドロップされますが、これを設定することでストレージアカウントに直接つながりルールを追加する必要がありません。また、他のネットワークからは疎通しなくなるので、セキュリティも向上します。ただし、Azure Portalからブラウズしてフォルダの中を見るようなこともできなくなりますので留意しておく必要があります。
なお、プロファイルのVHDを消したい、というようなときには、アクセス可能なネットワーク内のVMから
`net use z: \\<storage-account-name>.file.core.windows.net\<share-name> <storage-account-key> /user:Azure\<storage-account-name>`
というようなコマンドを発行して特権ユーザーでアクセスすることが可能です。ここで、最初のネットワークインフラのデプロイ時にWindows VMを一つ作っておくと役に立ちます。

# 使い方
## FSLogixの設定
イメージの中で設定してしまうこともできますし、グループポリシーで設定することもできます。ここではグループポリシーの設定方法を記載します。
まず、[ここ](https://aka.ms/fslogix_download)にあるFSLogixのパッケージファイルをPDC内にダウンロードします。
ダウンロードしたZipファイルを展開したら、下記のファイルをコピーします。

| ファイル | コピー先 |
|:--|:--|
| fslogix.admx | C:\Windows\PolicyDefinitions |
| fslogix.adml | C:\Windows\PolicyDefinitions\en-US |

グループポリシーで設定できるようになります。
![fslogix-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/684720/a34e390f-176c-be32-a16d-29f2f25d7637.png)

| Setting | Value |
|:--|:--|
| Enabled | On |
| Delete local profile when FSLogix Profile should apply | On |
| VHD Location | <ファイルシェアへのパス>  |

ファイルシェアへのパスは
`\\<storage_account_name>.file.core.windows.net\avdfileshare\Profiles`
となります。

## ユーザー作成
Active Directoryにユーザーを作成して、`AVD_Users`グループに登録することで、FSLogixのプロファイル置き場(ファイル共有)を利用できるようになっています。
![user-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/684720/fb231b6c-0307-5881-0bdb-ee747a8d8997.png)
![user-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/684720/c5d29e9b-6e3a-9bc0-5417-6dd3b221e7bd.png)

## AVD用イメージ
シングルセッション/マルチセッションで利用できるOSイメージが異なります。
特徴については、Azure Baseのブログ「[Windows 10 マルチセッション版の利用上の注意点](https://www.microsoft.com/ja-jp/events/azurebase/blog/wvd-windows-10-multi-session/)」が参考になります。
また、アプリケーションも、Microsoft 365 Apps等も入れるなど、利用環境/保有ライセンスによって個別に手配します。
一般的なWindows 10マルチセッションとMicrosoft 365 Appsを入れるイメージについては、別記事の「[Azure Virtual Desktopで使う日本語UIのWindows 10 + Officeのマスターイメージを作る](https://qiita.com/takeokams/items/4e0753047822b13bbcf7)」を公開しています。

## ホストプールの作成
AVDのホストプールの作成のポイントは、ネットワークはスポークネットワークを指定すること、ネットワークセキュリティグループはすでにスポークネットワークのサブネットに割当たっているので、追加での設定は不要です。
![host-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/684720/e3ef79c7-aba8-2334-dfef-2f209e56dbf3.png)

## ユーザーの割り当て
AVDのアプリケーショングループに`AVD_Users`グループを割り当てると、このグループに所属しているユーザーが、当該のAVDのアプリケーション(デスクトップを含む)にアクセスできるようになります。
![user-3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/684720/1d39ea29-1f0a-6e7b-fe19-c023d4f98696.png)
実環境ではアプリケーションやデスクトップのタイプ、ロケーションなどによってグループを分けて制御することになると思います。

## 監視/ログ設定
AVDの利用状況確認はAzure Monitorのブックを活用することができますが、設定が必要です。
別記事の「[WVDの監視機能であるAzure Monitorを使ってみる](https://qiita.com/takeokams/items/8cfb1dba57f7afe9653c)」が参考になると思います。
ファイアウォールのログはARMテンプレートで設定されています。
Log Analyticsのクエリで見ることもできますし、Azure MonitorのブックもARMテンプレートでデプロイされていますので、これを開いて確認することもできます。
![monitor-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/684720/3fcc3259-6caf-2612-fae0-87df1c379f51.png)

ファイアウォールについては、別記事「[サクッと検証用Azure Firewall Premiumを構築](https://qiita.com/takeokams/items/67c7cb5374e865dd27b6)」を公開しています。

## ファイアウォールのルール
このARMテンプレートでは、AVDの基盤に関するルールは設定されているのですが、それ以外のインターネットワークアクセスのルールは定義していないためアクセスできません。
![afw-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/684720/c257f8b6-cb83-d816-10e7-f13385158819.png)
例えばTeamsを起動させる場合は、ファイアウォールポリシーのアプリケーションルールに、Webカテゴリで「コンピュータとテクノロジ」を追加できます。
![afw-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/684720/32bf0149-f6b9-bc94-2885-429e1eebd35a.png)
![afw-3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/684720/40722d4a-4a54-0647-dd0a-ac312af7d8e1.png)
※ 2021年7月25日現在、Teamsを通すには`*teams.microsoft.com`をルールに追加することが必要になりました。

通過させるルールの作成はログを見ながらになると思いますが、別記事「[サクッと検証用Azure Firewall Premiumを構築](https://qiita.com/takeokams/items/67c7cb5374e865dd27b6)」が参考になります。

# 参考情報

- [AVD アーキテクチャー デザイン ガイド (Powered By FTA)](https://github.com/Azure/fta-japan/blob/main/OneToMany/WVD%20Architecture%20Design%20Guide.md)
- [エンタープライズ向けの FSLogix](https://docs.microsoft.com/ja-jp/azure/architecture/example-scenario/wvd/windows-virtual-desktop-fslogix)