Azure ポータルの作成画面をカスタマイズしてみる

Azure 上にリソースを作る方法は様々ありますが、Azure ポータルから作る方法が一番簡単です。また、ARM テンプレートでリソースを作る際、Azure CLI や PowerShell を使うことが多いかと思いますが、Azure ポータル上から展開することもできます。

この記事では、ARM テンプレートを使って Azure ポータルからリソースを作る際に、作成画面をカスタマイズできる機能を紹介します。

今回紹介する機能を使うとこんな感じの作成画面を作ることが出来るようになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132347/a53ba1ae-930c-504d-4305-6c1f9b54361e.png)

:::note info
上の例では、現状 API Management は Azure ポータルからゾーン対応したリソースが新規に作れないため、ARM テンプレートを作成し、UI をカスタマイズしています。
:::

# ARM テンプレートを Azure ポータルから展開する方法
カスタマイズする方法を説明する前に、まずは ARM テンプレートを Azure ポータルに貼り付けて展開する方法を紹介します。

ドキュメントはこちらをご覧ください。
クイック スタート:Azure portal を使用して ARM テンプレートを作成およびデプロイする
https://docs.microsoft.com/ja-jp/azure/azure-resource-manager/templates/quickstart-create-templates-use-the-portal

`カスタム テンプレートのデプロイ`を選択し、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132347/9a76c48d-72fd-ccd5-22d9-0256b16213e8.png)

テンプレートをそのまま貼り付けると
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132347/ec48cf95-41df-d387-e800-5db5dfca9f27.png)

こんな感じでポータルが出来上がります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132347/5971a3f5-be04-b339-add0-bb1b68b744c0.png)

出来上がった画面を見ると分かるように、Azure ポータルはテンプレートの内容からポータルをいい感じに作成してくれます。
例えば、"Ubuntu OS Version"のパラメーターは、allowedValues として許可される値が指定されているわけですが、そうすると Azure ポータルは"これはわざわざ入力させる必要はないからプルダウンにすればいいんだな"と解釈してくれます。

ちなみにこの画面ショットでは以下のテンプレートをそのまま貼り付けてみました。

Very simple deployment of a VM in an Availability Zone
https://github.com/Azure/azure-quickstart-templates/tree/master/quickstarts/microsoft.compute/vm-simple-zones

# ARM テンプレートを URL で指定してみる
最初の方法では、ARM テンプレートの中身をコピーして貼り付け、という方法で指定しましたが、これを URL で渡すことができます。

以下の URL をクリックしてみてください。
https://portal.azure.com/#create/Microsoft.Template/uri/https%3A%2F%2Fraw.githubusercontent.com%2FAzure%2Fazure-quickstart-templates%2Fmaster%2Fquickstarts%2Fmicrosoft.compute%2Fvm-simple-zones%2Fazuredeploy.json

そうすると、いきなり作成画面に遷移したと思います。この URL を分解してみるとこんな感じになっています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132347/b8457ab3-7026-6630-eb1f-95cb13c0065c.png)

いちいちテンプレートの中身をコピペしなくても、インターネット上のテンプレートを URL の一部で渡すことで、ポータル上からそのまま展開できるようになっているわけです。

# 作成画面をカスタマイズしてみる
ここからが本題です。
テンプレートの内容をコピペもしくは URL で指定する方法では、Azure ポータルが自動的に解釈してくれる方法で作成画面が作られました。

例えば以下の様なことをしたいときには、カスタマイズが必要になります。

- 仮想マシンの作成数をスライダーで表示させたい
- 既にある仮想ネットワークをテキストで入力させるのではなくプルダウンで指定させたい
- 作成画面に説明を入れたい

カスタマイズの手順としては次のステップで行います。

1. UI 定義ファイルを作成する
2. UI 定義ファイルを URL で指定する、もしくはテンプレートスペックに組み込む

## 1. UI 定義ファイルを作る
Azure ポータルの作成画面をカスタマイズするには、UI を定義するファイルを作成します。実は、この UI 定義は マネージドアプリケーションという機能の定義をそのまま(もしくはほぼそのまま)使うことができます。

マネージド アプリケーションとは？という方はこちらのドキュメントをご覧ください。
Azure マネージド アプリケーションの概要
https://docs.microsoft.com/ja-jp/azure/azure-resource-manager/managed-applications/overview

簡単に説明すると、Azure のさまざまなリソースを簡単な UI で作成するための機能で、例えば管理者側でマネージド アプリケーションを作成しておき、ユーザーはポータルからマーケットプレイスにあるサービスのように作成することを実現します。

このマネージドアプリケーションの UI 定義の内容をほぼそのまま Azure ポータルの作成画面の UI 定義に使うことが出来ます。

:::note info
マネージド アプリケーションの UI 定義は createUIDefinition などと呼ばれていますが、これを uiFormDefinition と呼ばれるものに置き換えてテンプレート スペックから汎用的に使えるようにすることが進められています。コンポーネントはほぼマネージド アプリケーションのものをそのまま使えますが、定義方法が変わるため書き換えが必要になります。本記事では UI Forms を前提とします。
ARM Template Specs now GA!(https://dev.to/azure/arm-template-specs-now-ga-161a) のサイトもご覧ください。
:::

では UI 定義はどう書けばいいのか、ということなのですが、残念ながら現状 uiFormDefinition としてまとまっているドキュメントは見つけられませんでした。
ただスキーマは公開されていること、基本的にマネージド アプリケーションの定義をほぼそのまま使えること、サンプルがいくつかあるためそれらを参考にすると悩まずに作成できます。

以下参考になるドキュメントやサンプルです。

- スキーマ
    - https://github.com/Azure/azure-resource-manager-schemas/blob/main/schemas/2021-09-09/uiFormDefinition.schema.json
- マネージド アプリケーション(createUIDefinition) のドキュメント
    - https://docs.microsoft.com/en-us/azure/azure-resource-manager/managed-applications/create-uidefinition-elements
- サンプル: CAF の エンタープライス スケール環境の展開テンプレート
    - https://github.com/Azure/Enterprise-Scale

ここではざっくりとどのような構造になっているか説明します。
以下のサンプルは、私の作成した UI 定義から抜粋したものです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132347/f2728683-61ac-a807-9c57-b854baf51523.png)

このように、ウィザードの各タブを `steps`、ページ内の要素を`elements`として定義することで自由自在にポータルを作り上げることができます。
そして、`outputs`では Azure ポータルの UI コンポーネントで生成された値を ARM テンプレートにパラメーターとして渡すための定義をします。

他にどのようなコンポーネントがあるかについては、スキーマとマネージド アプリケーションのドキュメントをご確認ください。
例えば、仮想マシンのサイズを選択する UI や
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132347/3ec80cc1-7a07-59ee-59a8-9507c1002612.png)
仮想ネットワークの情報を入力するための UI 等が用意されています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132347/f1711041-760f-42de-b60f-01a218680247.png)

他にも REST API を実行できるようなコンポーネントもあるため、いろいろと面白そうなことが出来そうです。

## 2. UI 定義ファイルを URL で指定する、もしくはテンプレートスペックに組み込む
作成した UI 定義ファイルを利用する方法として主に2通りあります。

### 2-1. URL で UI 定義を渡す
まずは、URL として渡す方法です。例えば以下の様な URL です。
https://portal.azure.com/#blade/Microsoft_Azure_CreateUIDef/CustomDeploymentBlade/uri/https%3A%2F%2Fraw.githubusercontent.com%2FtsubasaxZZZ%2Fterraform-azure%2Fmain%2Fapim-to-internal-withAZ%2F2_deploy-apim%2Fazuredeploy.json/uiFormDefinitionUri/https%3A%2F%2Fraw.githubusercontent.com%2FtsubasaxZZZ%2Fterraform-azure%2Fmain%2Fapim-to-internal-withAZ%2F2_deploy-apim%2Fuiform.json

構造としてはこのようになっています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132347/bfa3a014-52d6-8a6e-cf0e-989e461f7085.png)

少しだけ前の部分が変わっていますが、初めに紹介したテンプレートを指定する URL にUI 定義の URL を加えているだけです。

__つまり、テンプレートはそのまま変更することなく、UI だけを変更することができます。__
これは例えば公開されている自分が作成していないテンプレートに対しても UI を提供することが出来たり、UI を作る人とテンプレートを作る人を分けることが出来たりする等の点でメリットがあるでしょう。

### 2-2. テンプレート スペック作成時のオプションとして渡す
URL を渡す方法では、テンプレートも UI 定義もパブリックな場所に置いてあることが前提でした。しかし、テンプレートを非公開にしたい、Azure のリソースとして管理したい、という要望があると思います。

そんな時に使えるのがテンプレート スペックです。テンプレートを Azure のリソースとして作成でき、さらに作成時に UI 定義のファイルをオプションとして指定することができるため、完全に非公開かつ Azure のリソースとして管理することが可能になります。

テンプレート スペックを作成するコマンドはこちらにドキュメントがあります。
https://docs.microsoft.com/en-us/cli/azure/ts?view=azure-cli-latest#az_ts_create

`--ui-form-definition` に UI 定義の JSON ファイルを指定します。

例えば先ほどのテンプレートと UI 定義をテンプレート スペックに登録したい場合はこのようなコマンドになります。

```
az ts create --name apimWithAz --resource-group rg-templatespec --template-file azuredeploy.json --version 1.0 --ui-form-definition uiform.json
```

これでユーザーは Azure ポータルからリソースの展開が行えるようになります。

# まとめ
いかがでしたでしょうか。専用の UI を用意するとユーザーフレンドリーになるだけでなく、オペレーションミスも減らすことが期待できます。
また、既存のテンプレートに手を加えることなく、様々なパターンの UI を作れるため人や状況に応じた作成画面を作ることも可能です。
ぜひこの機能を活用ください。

最後までお読みいただきありがとうございました。