この記事は更新から24ヶ月以上経過しているため、最新の情報を別途確認することを推奨いたします。
パーソルプロセス&テクノロジーの内田です。
ARMテンプレートを用いて仮想マシンを作成、作成後に仮想マシン拡張機能を用いてADにドメイン参加するテンプレートを作成、解説していきたいと思います。
前回の記事はこちら。
ARMテンプレートからデプロイする#1 – Cloud Steady | パーソルプロセス&テクノロジー株式会社
また、Bicepを用いて、ドメインに参加したWindowsVMを作成するためのコード記述方法については下記記事に記載しています。
Bicepでドメインに参加したWindowsVMのコード記述方法 – Cloud Steady | パーソルプロセス&テクノロジー株式会社
ドメイン参加するためのリソースは何か
まず大前提として、ARMテンプレート ファイルは宣言型ですので、リソースがどのような設定であることが望ましいかという、状態を定義するものになります。
そのためARMテンプレートでできることは、仮想マシンやNIC、ディスクといったAzureリソースに対して特定のプロパティを設定した上でできることに焦点が置かれています。
ドメイン参加は仮想マシンのプロパティの話ではなく、OS上の操作となりますので、少し変わったリソースをデプロイします。
具体的にはMicrosoft.Computeリソース プロバイダーが提供する拡張機能リソースをデプロイします。拡張機能リソースのリソース タイプは「Microsoft.Compute/virtualMachines/extensions」であり、このリソース タイプによって、仮想マシン リソースに対する様々な追加設定を構成することが可能です。
今回は「仮想マシンのドメイン参加」を拡張機能リソースで設定することになりますが、他にも「Log Analytics Agentのインストール」などが可能です。
拡張機能リソースのテンプレート
それでは、拡張機能リソースのARMテンプレートを確認していきましょう。
まずdependOnを用いてドメイン参加をする仮想マシンリソースとの依存関係を示しています。
次にproperties.settings配下のオブジェクトにて、ドメイン名やOUパス、ドメイン参加する際の管理者ユーザーの指定をしています。
そして、properties.protectedSettings配下のオブジェクトにて、ドメイン参加する際の管理者ユーザーのパスワードを指定しています。
またもう一つ着目すべき点は拡張機能リソースのリソース名です。拡張機能リソースのリソースタイプは「Microsoft.Compute/virtualMachines/extensions」であり、仮想マシンのサブリソースであることがわかります。サブリソースのリソース名は「<親リソース名>/<サブリソース名>」という形式である必要がありますので、「<VM名>/domainJoin」というリソース名となっていることに注意しておきましょう。
実際にデプロイする
VMやNICのテンプレートを追加した後、実際にこのリソースをデプロイしていきたいと思います。なお、デプロイ先のVnetにはあらかじめDNS設定をしておきます。
デプロイ先のリソースグループにアクセスして「非表示の型の表示」をオンにすると、拡張機能サブリソースがデプロイされていることが確認できます。
最後に今回のARMテンプレートをサンプルとして下記に公開いたします。デプロイするリソースの構成情報をオブジェクト化して、ループ処理を付け加えれば、複数の仮想マシンを1度のデプロイ処理で作成でき、なおかつそれらのドメイン参加が自動的に行われますので、構築に掛かる工数を削減することが見込めます。
今回の内容は以上となります。
蛇足ですが、現在のIaCの主流はARMテンプレートからBicepに置き換わりつつあると考えます。今回のARMテンプレートにおいても、Bicepから作成をしております。ARMと遜色なくBicepを利用可能であることを最後に補足しておきます。
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"adminUserName": {
"type": "String"
},
"adminPassword": {
"type": "SecureString"
},
"domainName": {
"type": "String"
},
"ouPath": {
"type": "String",
"metadata": {
"description": "OU=xxx,OU=xxx,DC=xxx,DC=xxx という形式で入力する。"
}
},
"domainAdminUserName": {
"type": "String",
"metadata": {
"descriptipn": "UPN形式で入力する必要がある。username@domainname"
}
},
"domainAdminPassword": {
"type": "SecureString"
}
},
"variables": {
"hostNameClassification": "test"
},
"resources": [
{
"type": "Microsoft.Compute/virtualMachines/extensions",
"apiVersion": "2021-07-01",
"name": "[format('{0}/{1}', format('vm-{0}-1', variables('hostNameClassification')), 'domainJoin')]",
"location": "[resourceGroup().location]",
"dependsOn": [
"[resourceId('Microsoft.Compute/virtualMachines', format('vm-{0}-1', variables('hostNameClassification')))]"
],
"properties": {
"publisher": "Microsoft.Compute",
"type": "JsonADDomainExtension",
"typeHandlerVersion": "1.3",
"autoUpgradeMinorVersion": true,
"settings": {
"name": "[parameters('domainName')]",
"ouPath": "[parameters('ouPath')]",
"user": "[parameters('domainAdminUserName')]",
"restart": "true",
"options": "3"
},
"protectedSettings": {
"password": "[parameters('domainAdminPassword')]"
}
}
},
{
"type": "Microsoft.Compute/virtualMachines",
"apiVersion": "2021-07-01",
"name": "[format('vm-{0}-1', variables('hostNameClassification'))]",
"location": "[resourceGroup().location]",
"dependsOn": [
"[resourceId('Microsoft.Network/networkInterfaces', format('nic-{0}-1', variables('hostNameClassification')))]"
],
"zones": [],
"properties": {
"hardwareProfile": {
"vmSize": "Standard_A2_v2"
},
"osProfile": {
"computerName": "[format('vm-{0}-1', variables('hostNameClassification'))]",
"adminUsername": "[parameters('adminUserName')]",
"adminPassword": "[parameters('adminPassword')]"
},
"storageProfile": {
"imageReference": {
"publisher": "MicrosoftWindowsServer",
"offer": "WindowsServer",
"sku": "2019-Datacenter",
"version": "latest"
},
"osDisk": {
"name": "[format('disk-{0}-OsDisk', variables('hostNameClassification'))]",
"caching": "ReadWrite",
"createOption": "FromImage"
}
},
"networkProfile": {
"networkInterfaces": [
{
"id": "[resourceId('Microsoft.Network/networkInterfaces', format('nic-{0}-1', variables('hostNameClassification')))]"
}
]
},
"diagnosticsProfile": {
"bootDiagnostics": {
"enabled": true
}
}
}
},
{
"type": "Microsoft.Network/networkInterfaces",
"apiVersion": "2020-11-01",
"name": "[format('nic-{0}-1', variables('hostNameClassification'))]",
"location": "[resourceGroup().location]",
"properties": {
"ipConfigurations": [
{
"name": "ipConfiguration1",
"properties": {
"privateIPAllocationMethod": "Dynamic",
"subnet": {
"id": "[extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, 'RGNAME'), 'Microsoft.Network/virtualNetworks/subnets', 'VNETNAME', 'SUBNETNAME')]"
}
}
}
]
}
}
]
}