-
Notifications
You must be signed in to change notification settings - Fork 0
MS_ARMTemplate
- 戻る
-
ARM テンプレートとも。
-
Azure では、主に ARM テンプレートを利用して、
インフラ〜OS レイヤまでのインフラ構築の「自動化(IaC)」を行う
補足(最新化 / Bicep): 現在、ARM テンプレート(JSON)を
直接書くことは推奨されていない。
Bicep という DSL が用意されており、
これをコンパイルすると ARM テンプレートになる。Bicep(.bicep)──ビルド──▶ ARM テンプレート(.json)──▶ ARM API 人が書く 機械が読むBicep の利点は、
- 記述量が半分以下になる(
[parameters('x')]のような文字列式が不要)、- 依存関係が自動推論される(後述の
dependsOnの苦労が大幅に減る)、- 型チェックと補完が効く、
という点。本ページが述べている苦労の多くは Bicep で解消される。
ただし、ARM テンプレートの構造(parameters / variables / resources /
outputs、resourceId の考え方)はそのまま Bicep にも通じるため、
以下の内容は現在も理解する価値がある。
Resource Manager はテンプレートを解析し、
その構文を適切なリソース・プロバイダの REST API 操作に変換する。
既存のリソース・グループのテンプレートの取得
- リソース・グループの現在の状態をエクスポート
- 特定のデプロイに使用されたテンプレートを表示
ARM テンプレートとパラメタ・ファイルから構成される
作成するリソース群を指定する(template.json)。
- 可変要素をパラメタ化する(parameters.json)。
- テンプレート実行時に外部から値を与える。
Visual Studio Code に ARM Tools プラグインを入れ編集。
Azure ポータルから保存・実行すると便利。
※ ローカルで実行するには、PowerShell ライブラリのインストールなど環境構築が必要になる。
補足(最新化): 現在は Azure CLI で完結する。
# 事前確認(差分を見る) az deployment group what-if -g <RG名> --template-file main.bicep # 適用 az deployment group create -g <RG名> --template-file main.bicep --parameters @params.json特に
what-if(What-If 操作) は、
「このテンプレートを適用すると何が変わるか」を事前に表示する機能で、
本ページ後半の「配置が成功するまで trial and error」の苦労を
大幅に軽減する。
-
スクラッチで記載するのは難しいので、
Automation オプション、Automation スクリプトを使用する。 -
リソースの作成前 or 作成後でやり方が変わってくる。
-
リソース作成時にテンプレートを引き抜く。
ポータルからのリソース作成時に、Automation オプションを確認 -
リソース作成後にテンプレートを引き抜く。
リソース・グループまたはリソースから、Automation スクリプトを出力
-
-
以下のトレード・オフがあるので、
2つの方法を併用して作成する。
| Automation オプション<br>リソース作成時にテンプレートを引き抜く。 | Automation スクリプト<br>リソース作成後にテンプレートを引き抜く。 | |
|---|---|---|
| GOOD | 綺麗な JSON が入手できる | 合体(依存関係アリ、構成変更後)の JSON を入手できる。 |
| BAD | ・一部の新しいリソースでサポートされていない。<br>・全てがパラメタライズされた状態の JSON。<br>・単体(依存関係ナシ、構成変更前)の JSON しか入手できない。 | ・リソースによっては、JSON 化出来ないモノがある。<br>・半端にパラメタライズされた状態の JSON。<br>・余分な値や、重複した出力がされることがある。 |
補足(この 2 つの使い分けが本ページの核): ポータルで作った構成から
テンプレートを「引き抜く」という手法は、
ゼロから JSON を書くのが非現実的であるという現実に即した実践知である。【Automation オプション】= 作成前のプレビュー ポータルの [確認と作成] の直前で見られる → 綺麗だが、そのリソース単体のみ 【Automation スクリプト】= 作成後のエクスポート リソース グループの [テンプレートのエクスポート] → 全体が取れるが、余計な値まで付いてくる「綺麗な単体」と「汚い全体」を突き合わせて手で組む、
というのが本ページの手法である。
ハブネットワークの ARM テンプレート作成
※ 以下、サンプル・シナリオの手順
仮想ネットワークの作成
リソース作成時のテンプレート引き抜き機能を使用する。
-
ポータル上で仮想ネットワーク、Azure Firewall(+パブリック IP)を構成する。
-
作成前に、Automation オプションを選択し、
ARM テンプレートとパラメタ・ファイルを引き抜く。 -
テンプレートに、基本的な修正を施す。
-
テンプレートの修正後、実際にリソースを作成する。
- 作成したテンプレートを Azure ポータルから登録し、展開をテスト
- 記述にバグがある場合には配置が失敗する → 配置が成功するまで、trial and error。
既存リソースから、リソース作成後のテンプレート引き抜き機能を使用する。
(作成時は引き抜き不可であるため)
-
先ず、ポータル上でサブネットを3つ構成する(仮想ネットワークのサブ・リソース)。
- 管理 VM 用
- DNS 等配置用
- Gateway 用
-
作成後に、Automation スクリプトを選択すると、
当該リソースが含まれるリソース・グループ全体を
ARM テンプレートとパラメタ・ファイルに引き抜く。 -
Automation スクリプトの特徴。
- リソース・グループ全体が引き抜かれる。
- 既定値や、現在の状態など、余分なパラメタ値が引き抜かれる。
- サブ・リソースが独立したリソースとして展開される。
- このため、全体的に冗長になる。
- また、依存関係が展開先に変更される。
-
Automation スクリプトをテンプレートにマージする。
-
コチラのテンプレートをベースに、Automation スクリプトを参考にして、
展開されたリソース(サブネット)は、(仮想ネットワークの)サブ・リソース的にマージする。- ココでは、サービス・エンドポイントの定義が追加されているのでコレもマージする。
- 既定値や、現在の状態など、GUI から設定していない余分な値は、移行しないようにする。
-
最後に、テンプレートに、基本的な修正を施す。
-
-
テンプレートの修正後、実際にリソースを作成する。
補足(サブ・リソースの 2 通りの書き方): サブネットのような
「親に属するリソース」は、ARM では 2 通りに書ける。// ① 親の中に入れ子で書く(本ページが推奨する形) { "type": "Microsoft.Network/virtualNetworks", "properties": { "subnets": [ { "name": "mgmt", ... } ] } } // ② 独立したリソースとして書く(エクスポートされる形) { "type": "Microsoft.Network/virtualNetworks/subnets", "name": "vnet/mgmt", ... }①と②を混在させると、デプロイのたびにサブネットが消えるという
事故が起きる(① 側の定義が ② を上書きするため)。
原文が「サブ・リソース的にマージする」と一貫して述べているのは、
この事故を避けるための判断である。
ルート・テーブル(UDR)の作成
同様に、既存リソースから、リソース作成後のテンプレート引き抜き機能を使用する。
(リソース依存関係の指定がポイント)
-
ポータル上でルート・テーブル(UDR)を構成する。
-
Automation オプションを確認する(依存関係ナシ、構成変更前)。
-
上記のルート・テーブルをポータル上で実際に作成し、
-
Automation スクリプトを生成する(依存関係アリ、構成変更後)。
-
Automation スクリプトを確認する。
- ルート・テーブルとルートが生成され、関連付けは、サブネット側に入る。
- ルート・テーブルのサブ・リソースのルートが展開され、重複して出力される。
※ 前段階の Automation スクリプトと Diff を取るなどすると良さそうではある。
-
Automation スクリプトをテンプレートにマージする。
-
テンプレートの修正後、実際にリソースを作成する。
VPN Gateway の作成
再び、リソース作成時のテンプレート引き抜き機能を使用する。
(テンプレートに含めるリソースの範囲がポイント)
-
ポータル上で Gateway 用サブネットに、
VPN Gateway(+パブリック IP)を構成する。
(対向ネットワークが無いと設定できない所は構成しない等) -
作成前に、Automation オプションを選択し、
ARM テンプレートとパラメタ・ファイルを引き抜く。 -
Automation オプションをテンプレートにマージする。
-
リソース作成後のテンプレート引き抜き機能を使用した後に、
リソース作成時のテンプレート引き抜き機能を使用する場合、
(既にあるリソースが前提になっているので)
以下の様に依存関係の修正が必要になることがある。- 定義にリソースを識別する固定値の ID が使用されている場合、
resourceId 関数を使用した動的解決が必要になることがある。 - また、依存関係設定は、親同士の依存関係に置き換えると良い。
- 定義にリソースを識別する固定値の ID が使用されている場合、
-
最後に、テンプレートに、基本的な修正を施す。
-
-
テンプレートの修正後、実際にリソースを作成する。
Azure Firewall の設定
既存リソースからのテンプレート引き抜き機能に対応していない場合の扱い方
現時点では、上記の引き抜き機能が実装された。
(されていない場合は、リファレンス頼りになる)
-
ポータル上で Azure Firewall に以下を構成する。
- Windows Update
- DNS クエリ
-
上記をポータル上で実際に適用し、
-
Automation スクリプトを生成・確認する。
-
Automation スクリプトをテンプレートにマージする。
-
Azure Firewall の、properties の、
xxxxxRuleCollections をテンプレートにマージする。 - 最後に、テンプレートに、基本的な修正を施す。
-
Azure Firewall の、properties の、
-
テンプレートの修正後、実際にリソースを作成する。
診断ログ・ストレージの作成
再び、リソース作成時のテンプレート引き抜き機能を使用する。
(グローバル一意リソースが存在するケース)
-
ポータル上でストレージ・アカウントを構成する。
-
作成前に、Automation オプションを選択し、
ARM テンプレートとパラメタ・ファイルを引き抜く。 -
Automation オプションをテンプレートにマージする。
-
ストレージ・アカウントのセクションをテンプレートにマージする。
-
最後に、テンプレートに、基本的な修正を施す。
-
-
テンプレートの修正後、実際にリソースを作成する。
(この際、グローバル一意リソース用の変数入力が求められる)
補足(グローバル一意リソース): ストレージ アカウント名は
全世界で一意である必要がある(<名前>.blob.core.windows.netという
FQDN になるため)。
したがって、テンプレートに固定名を書くと他人と衝突して失敗する。
後述の parameters / variables で
「共通のプレフィックス + 環境ごとの識別子」を組み立てるのが定石。現在は
uniqueString(resourceGroup().id)関数を使い、
リソース グループごとに決定的な一意文字列を生成する方法が一般的。
仮想マシンの作成1
管理 VM 用サブネットに管理用の仮想マシンを作成するが、
仮想マシンでは、
- リソース作成時のテンプレート引き抜き機能と
- リソース作成後のテンプレート引き抜き機能とを
併用する(そして、評価式の修正のコツがポイント)。
-
ポータル上で仮想マシンを構成する。
-
作成前に、Automation オプションを選択し、
ARM テンプレートとパラメタ・ファイルを引き抜く。 -
Automation オプションをテンプレートにマージする。
-
パスワードは、グローバル一意リソース同様、
parameters セクションに変数を追加する(が、型は secureString にする) -
parameters セクションに変数の加工が必要な場合、variables セクションが使用されている。
variables を使用しないように展開すると、この中に動的解決すべきパラメタを確認できるので、
この値を resourceId で動的解決する(NIC が利用するサブネットや NSG の ID が該当する)。 -
最後に、テンプレートに、基本的な修正を施す。
-
-
上記の仮想マシンをポータル上で実際に作成し、
-
Automation スクリプトを生成・確認する。
すると、追加で以下の依存関係が確認できる。- NIC → (サブネット)
- 仮想マシン → (ストレージ・アカウント)
-
Automation スクリプトをテンプレートにマージする。
-
テンプレートの修正後、実際にリソースを作成する。
(この際、グローバル一意リソース用の変数入力が求められる)
補足(secureString の重要性): パスワードを
string型で受けると、
デプロイ履歴にパラメータの値が平文で残る(ポータルから見える)。
secureStringにすると値がログに残らない。より安全なのは、Key Vault から参照する方式である。
"adminPassword": { "reference": { "keyVault": { "id": "/subscriptions/.../vaults/myVault" }, "secretName": "vmAdminPassword" } }こうすると、パラメータ ファイルに秘密そのものを書かずに済む。
仮想マシンの作成2
DNS 等配置用サブネットに DNS サーバ用の仮想マシンを作成するので、
冗長化のタメに可用性セットに2台の仮想マシンを配置するが、
この場合、1台作成してコピペで増やすという方法が採れる。
-
先ず、ポータル上で可用性セットを作成する。
-
作成前に、Automation オプションを選択し、
ARM テンプレートとパラメタ・ファイルを引き抜く。 -
Automation オプションをテンプレートにマージする。
-
上記の可用性セットをポータル上で実際に作成し、
-
作成前に、Automation オプションを選択し、
ARM テンプレートとパラメタ・ファイルを引き抜く。 -
Automation オプションをテンプレートにマージする。
-
上記の仮想マシンをポータル上で実際に作成し、
-
Automation スクリプトを生成・確認する。
すると、追加で以下の依存関係が確認できる。- NIC → (サブネット)
- 仮想マシン → (ストレージ・アカウント、可用性セット)
-
Automation スクリプトをテンプレートにマージする。
-
最後に、仮想マシンをコピペで増やし、リネームし、衝突が無いことを確認する。
(アンチ・マルウェアなどを構成すると、VM 名が含まれないリソースが含まれるケースもあるらしい)。 -
テンプレートの修正後、実際にリソースを作成する。
(この際、グローバル一意リソース用の変数入力が求められる) -
更に、静的 IP を構成して、追加のフィードバックを行う。
- Automation スクリプトを生成・確認する。
- スクリプトをテンプレートに Diff &マージ。
- 静的 IP は NIC のコンフィギュレーションらしい。
補足(「コピペで増やす」の代替): 原文の手法は素朴だが確実である。
現在は **copy要素(Bicep ではforループ)**で
同じ定義を N 個展開できる。resource vm 'Microsoft.Compute/virtualMachines@2023-03-01' = [for i in range(0, 2): { name: 'dns-vm-${i}' ... }]コピペだと片方だけ直して不整合になる事故が起きやすいため、
台数が増えるならループにする方がよい。
ただし原文が指摘する「VM 名が含まれないリソース」の衝突は
ループでも起きるため、確認は必要。
Automation を使用してテンプレートを作成する際のポイントのまとめ。
何れの場合も、以下の、基本的な修正を施す。
-
テンプレート内のパラメタ値の具体値化を行う。
- template.json の resources セクションの
"[parameters('XXXX')]"を、
parameters.json の parameters セクションの具体値に変える。 - 具体値に変えた、template.json の parameters セクションのパラメタを削除する。
- template.json の resources セクションの
-
既定で GUI からの入力を使用するパラメタの動的値化を行う。
-
リソース・グループ名(name)、リソースを作成する場所(location)
-
"[parameters('XXXX')]"だった所を"[resourceGroup().XXXX]"に変更する。
(これでテンプレートを実行する際に与えられるパラメタを使用するらしい)
-
-
冗長な concat 関数は文字列にしてしまう。
補足(この「具体値化」の意図): 一見すると IaC の原則に反する
(パラメータ化を戻している)ように見えるが、これは合理的である。ポータルからエクスポートすると、変える必要のない値まで
すべてパラメータ化される。
その結果、parameters が数十個並び、
本当に変えたい値がどれか分からなくなる。【エクスポート直後】parameters が 40 個 → 何を渡せばいいのか不明 【整理後】 parameters が 3 個 → 環境ごとに変わるのはこれだけ**「環境ごとに変わるものだけをパラメータにする」**という原則に
戻す作業、と理解するとよい。
グローバル一意リソースが存在する場合などのケースで利用する。
-
parameters セクションを使用すると、
実行時にユーザ入力を反映できる。- parameters セクションに変数を追加する。
"parameters": {
"virtualDataCenterId": {
"type": "string",
"defaultValue": ""
}
},- グローバル一意リソース名などに(文字列連結で)反映する。
"name": "[concat('xxxxxx', parameters('virtualDataCenterId'))]",-
variables セクションを使用すると、
parameters セクションの変数を加工できる。- variables セクションに変数を追加し parameters を加工する。
"variables": {
"diagnosticsStorageAccountName": "[concat('azrefarchubrgdiag', parameters('virtualDataCenterId'))]"
},- グローバル一意リソース名などに variables を使用する。
"name": "[variables('diagnosticsStorageAccountName')]",仮想ネットワーク作成時、
リソース作成時のテンプレート引き抜き機能を使用して、
テンプレートを新規作成。
-
以降、基本的には、既存リソースから、
リソース作成後のテンプレート引き抜き機能を使用して、
Automation スクリプトをテンプレートにマージ。- 展開されたリソースはマージせず、
- サブ・リソースのみをテンプレートにマージする。
- 同様に、依存関係を分析して、依存関係を設定し直す。
-
再び、リソース作成時のテンプレート引き抜き機能を使用して、
Automation オプションをテンプレートにマージする場合、
※ 仮想マシン等では、上記2つの方法を併用する。
-
依存関係設定
-
基本的に、サブ・リソースは使用せず、
親同士の依存関係に置き換えると良い。 -
再び、Automation オプションを使用する場合、
(既にあるリソースが前提になっているので)依存関係の修正が必要になることがある。- 定義にリソースを識別する固定値の ID が使用されている場合、
resourceId 関数を使用した動的解決が必要になることがある。 - また、依存関係設定は、親同士の依存関係に置き換えると良い。
- 定義にリソースを識別する固定値の ID が使用されている場合、
-
-
dependsOn の ID の書き方
文字列と関数の2種類あり、文字列を使用する方法では、
簡便な記述ができるようになっているが、指定が曖昧になり易い。- 文字列:
"Microsoft.Network/virtualNetworks/azrefarc-hub-vnet/subnets/mgmt" - 関数:
"[resourceId(resourceGroup().name, 'Microsoft.Network/virtualNetworks/subnets', 'azrefarc-hub-vnet', 'mgmt')]"
- 文字列:
補足(Bicep なら不要になる作業): この節が扱っている
dependsOnの手作業とresourceIdの組み立ては、
ARM テンプレート(JSON)を書くうえで最も骨の折れる部分である。Bicep では、他のリソースのプロパティを参照した時点で
依存関係が自動的に推論されるため、原則dependsOnを書かない。resource vnet 'Microsoft.Network/virtualNetworks@2023-05-01' = { ... } resource nic 'Microsoft.Network/networkInterfaces@2023-05-01' = { properties: { ipConfigurations: [{ properties: { // vnet を参照 → 自動的に vnet への依存が設定される subnet: { id: vnet.properties.subnets[0].id } } }] } }本ページの「親同士の依存関係に置き換える」という工夫も、
Bicep では意識せずに正しい形になる。
-
リソース・グループ名を変えることによって、
- 並行展開が可能で素早く作業をすすめることが出来る。
- ただし、課金がされるので、並行してリソース・グループの開放を行う。
-
テンプレートが複雑、展開に時間のかかる
リソースは最後にテンプレに追加するようにする。- VPN Gateway の作成
-
仮想マシンの作成1、2
- JSON 定義がかなり大きなサイズになる。
- 仮想ネットワーク、サブネットなどに比べるとデプロイに時間もかかるため(?)
補足(VPN Gateway が遅い理由): VPN Gateway の作成には
30〜45 分かかる(バックエンドで専用の VM が構成されるため)。
試行錯誤の最後に回す、という原文の判断は極めて実践的である。
同様に時間のかかるものとして、Azure Firewall、
Application Gateway、AKS がある。現在は
what-ifで構文・参照の誤りを事前に潰せるため、
「作ってみて失敗する」回数自体を減らせる。
-
そもそもクラウドのインフラ構築は、
「trial and error」な所があるため、
序盤に着手すると手戻りが大きくなる可能性がある。 -
故に、構築の序盤にはポータルを使用し、
熟れてから、テンプレート化を開始するようにする。
補足(この結論が本ページの白眉): 「IaC は最初からやるべき」という
一般論に対し、**「構成が確定してから」**という現実的な指針を
示している点が本ページの価値である。IaC (Infrastructure as Code) が述べる
「適切なターゲットに有効」「スケール・メリットが必要」という留保と
同じ趣旨であり、
- 構成を探索する段階はポータル(速い、試しやすい)
- 構成が固まった段階でテンプレート化(再現性、監査性)
という段階分けが実務に即している。
なお、この判断は同じ環境を何面も作る予定があるかで変わる。
最初から複数環境が確定しているなら、早めにコード化した方がよい。
- Azure Resource Manager テンプレート入門と作成 | ブログ一覧 | DATUM STUDIO 株式会社
https://datumstudio.jp/blog/azure-resource-manager-%E3%83%86%E3%83%B3%E3%83%97%E3%83%AC%E3%83%BC%E3%83%88%E5%85%A5%E9%96%80%E3%81%A8%E4%BD%9C%E6%88%90
- Azure Resource Manager テンプレート
https://azure.microsoft.com/ja-jp/products/arm-templates/
-
Azure Resource Manager
-
テンプレートの概要
https://learn.microsoft.com/ja-jp/azure/azure-resource-manager/templates/overview -
テンプレートをデプロイする - Azure portal
https://learn.microsoft.com/ja-jp/azure/azure-resource-manager/templates/quickstart-create-templates-use-the-portal -
テンプレートのベスト プラクティス
https://learn.microsoft.com/ja-jp/azure/azure-resource-manager/templates/best-practices -
テンプレートの構造と構文
https://learn.microsoft.com/ja-jp/azure/azure-resource-manager/templates/syntax -
Bicep とは
https://learn.microsoft.com/ja-jp/azure/azure-resource-manager/bicep/overview -
What-If 操作
https://learn.microsoft.com/ja-jp/azure/azure-resource-manager/templates/deploy-what-if
-
-
Azure Virtual Machines
- クイック スタート:Resource Manager テンプレートを使用して Windows VM を作成する
https://learn.microsoft.com/ja-jp/azure/virtual-machines/windows/quick-create-template - クイック スタート:Resource Manager テンプレートを使用して Ubuntu Linux VM を作成する
https://learn.microsoft.com/ja-jp/azure/virtual-machines/linux/quick-create-template
- クイック スタート:Resource Manager テンプレートを使用して Windows VM を作成する
-
ARMTemplate デプロイ用の Json をイジる
https://qiita.com/sat0tabe/items/7d268d140aa849fbb665 -
Azure の ARM テンプレートを理解する
- part1 (基本編)
https://qiita.com/j-tsurumi/items/cc86e9412349da80a323 - part2 (ネットワークリソース編)
https://qiita.com/j-tsurumi/items/d7e9eda9da223764a799
- part1 (基本編)
-
Azure Resource Manager テンプレートを
- 使用した仮想マシンのデプロイ
https://qiita.com/yuki451/items/9a6bfc0e544cdcc32788 - 使用した自動シャットダウンの設定
https://qiita.com/yuki451/items/347cac19e6a76455edb6 - 使う複数のパラメーターをまとめてデプロイする PowerShell スクリプト
https://qiita.com/yuki451/items/d8b1e5c9b8de8e9f2462
- 使用した仮想マシンのデプロイ
-
ARMTemplate で AzureDNS のリソース作成とレコードを設定する(CLI もあるよ)
https://qiita.com/HiroyukiSakoh/items/6d3538303bbc310dd59f -
Azure Function v2 に HttpClientFactory+Polly
を組み込み、HttpClient の再試行を実装する
https://qiita.com/HiroyukiSakoh/items/92d1365db6447bd64550
FgCF > ゼロトラスト型マルチクラウド IT 環境 > Azure による仮想データセンタ構築手法
> 共通技術 > ネットワーク基盤の構成方法 > ARM テンプレートの利用方法
※ 体系・pwd は FgCF (Financial-grade Cloud Fundamentals) を参照。
- Azure CLI から ARM テンプレートを利用して Ubuntu をデプロイする
https://tech-lab.sios.jp/archives/2975
Tags: 移行, インフラストラクチャ, クラウド, セキュリティ, Azure, IaC
このWikiは「Open棟梁Project」,「OSSコンソーシアム 開発基盤部会」によって運営されています。