Azure がついに 7 周年らしいですね。おめでとうございます。(私は 20 歳で触り始めたので、気づけば 6 年以上使っていることに…。)
さて、昨日同僚から、「明日のトレーニングで使う VM を 40 台作りたい」と相談を受けて、片手間でデプロイしたので、落書き程度にメモを残しておきます。
1. 展開方法
詳しく話を聞くと、RDS 環境のトレーニング用に VM 5 台 (CB, SH1, SH2, Web, Client) x8 セットが明日までに欲しいとのこと。
パッと思いつく方法としては、以下の 4 通りくらいでしょうか。
- ポータルからポチポチする (論外)
- Azure PowerShell で単純にループさせてシリアルでデプロイする (遅い)
- Azure PowerShell でパラレルでデプロイする (面倒)
- JSON テンプレートを使う
どの方法でも作れますが、今日はデプロイに時間をかけられないので JSON にしました。(夕方相談を受けて、明日使うということだったので。)
なお、余談ですが PowerShell で複数リソースをパラレル展開する方法は以下にメモってあります。ただ、これも作成するリソース数が増えると、エラーを吐きやすくなってデバッグが面倒なので、今回は候補から除外。
- Azure PowerShell で多数のリソースを並列作成する
https://www.syuheiuda.com/?p=3641
2. JSON テンプレートの作り方
使い慣れていない人に PowerShell とか JSON テンプレートって言うとあからさまに嫌な顔されるんですが、一回作って慣れてしまえば大したことはないです。
JSON が初めての人は、横着せずに以下全部きっちり目を通しましょう。これだけ知っていれば十分なので。
- 驚愕! Azure リソース マネージャを利用した Infrastructure as Code 実践
https://channel9.msdn.com/Events/de-code/2016/INF-011
https://doc.co/8HhQuq
で、具体的にどう作るかというと、既存のテンプレートをパクってきて切り貼りします。
- Azure Quickstart Templates
https://github.com/Azure/azure-quickstart-templates
今回は VM を大量に複製したいので、名前に loop と入った以下をベースにします。
- 201-vm-copy-index-loops
https://github.com/Azure/azure-quickstart-templates/tree/master/201-vm-copy-index-loops
このまま [Deploy to Azure] ボタンでサクっとデプロイできるのですが、40 と入れると 5 台までしか作れないとエラーになります。生の JSON を開いてみると、以下の通り numberOfInstances のパラメーターが maxValue 5 となっているので、40 などに書き換えてしまいましょう。
なお、運用環境の場合は 1 つのストレージ (20000 IOPS 上限) に大量の VHD (500 IOPS 上限) を配置するとパフォーマンスに影響があるので、適切にストレージを分割する必要があります。あと、Premium ストレージについては 35 TB の容量制限もあるので気を付けましょう。
"numberOfInstances": {
"type": "int",
"defaultValue": 2,
"minValue": 2,
"maxValue": 5,
"metadata": {
"description": "Number of VMs to deploy, limit 5 since this sample is using a single storage account"
}
},
次に Visualize ボタンを押して含まれるリソースを確認すると以下が入っていることがわかります。リソース名に copyindex() とついている VM と NIC は、1 つしか定義されていませんが、ループさせて必要数だけ作成されるようになっています。
生の JSON をさらに深堀してみると、例えば NIC は以下のように定義されています。name は nic0, nic1, nic2… などとなるように、copyindex() でループのカウンタ (0, 1, 2…) をセットして、concat で文字列を結合しています。また、copy セクションで count として設定されている数だけループするように定義してあります。(ここでは、あとで任意の値が設定できるよう、numberOfInstances というパラメーターが入っています。)
{ "type": "Microsoft.Network/networkInterfaces", "name": "[concat('nic', copyindex())]", "apiVersion": "2016-03-30", "location": "[resourceGroup().location]", "copy": { "name": "nicLoop", "count": "[parameters('numberOfInstances')]" }, "dependsOn": [ "[variables('virtualNetworkName')]" ], "properties": { "ipConfigurations": [ { "name": "ipconfig1", "properties": { "privateIPAllocationMethod": "Dynamic", "subnet": { "id": "[variables('subnet1Ref')]" } } } ] } },
同じく VM についても 1 台分しか定義されていませんが、ループさせて numberOfInstances 台だけ展開されるようになっています。その他、コンピューター名やVHD のパス、NIC の ID なども copyIndex() を使って定義されていることに気を付けましょう。
{ "type": "Microsoft.Compute/virtualMachines", "name": "[concat('myvm', copyIndex())]", "apiVersion": "2016-03-30", "location": "[resourceGroup().location]", "copy": { "name": "virtualMachineLoop", "count": "[parameters('numberOfInstances')]" }, "dependsOn": [ "nicLoop", "[variables('storageAccountName')]" ], "properties": { "availabilitySet": { "id": "[resourceId('Microsoft.Compute/availabilitySets', variables('availabilitySetName'))]" }, "hardwareProfile": { "vmSize": "Standard_D1_v2" }, "osProfile": { "computerName": "[concat('vm', copyIndex())]", "adminUsername": "[parameters('adminUsername')]", "adminPassword": "[parameters('adminPassword')]" }, "storageProfile": { "imageReference": "[variables('imageReference')]", "osDisk": { "name": "osdisk", "vhd": { "uri": "[concat(reference(variables('StorageAccountName'), '2016-01-01').primaryEndpoints.blob, 'vhds/osdisk', copyIndex(), '.vhd')]" }, "caching": "ReadWrite", "createOption": "FromImage" } }, "networkProfile": { "networkInterfaces": [ { "id": "[resourceId('Microsoft.Network/networkInterfaces',concat('nic', copyindex()))]" } ] } } }
各パラメーターを一通り見てみると、実は Public IP が付与されていないことが判明します。このままでは直接 RDP できないので、他の Public IP 付きの VM を展開するテンプレートから Public IP の定義と、NIC の依存関係の部分をパクってきます。
なお、この際にリソース名等に使われている変数 (variables) が定義されていなかったりするので、concat(‘pip’, copyIndex()) などへ変更し、Public IP と NIC を紐づけるなど、ベースのテンプレートと整合性が取れるように微修正します。
- 101-vm-simple-windows
https://github.com/Azure/azure-quickstart-templates/tree/master/101-vm-simple-windows
{ "apiVersion": "2016-03-30", "type": "Microsoft.Network/publicIPAddresses", "name": "[variables('publicIPAddressName')]", "location": "[resourceGroup().location]", "properties": { "publicIPAllocationMethod": "Dynamic", "dnsSettings": { "domainNameLabel": "[parameters('dnsLabelPrefix')]" } } },
{ "apiVersion": "2016-03-30", "type": "Microsoft.Network/networkInterfaces", "name": "[variables('nicName')]", "location": "[resourceGroup().location]", "dependsOn": [ "[resourceId('Microsoft.Network/publicIPAddresses/', variables('publicIPAddressName'))]", "[resourceId('Microsoft.Network/virtualNetworks/', variables('virtualNetworkName'))]" ], "properties": { "ipConfigurations": [ { "name": "ipconfig1", "properties": { "privateIPAllocationMethod": "Dynamic", "publicIPAddress": { "id": "[resourceId('Microsoft.Network/publicIPAddresses',variables('publicIPAddressName'))]" }, "subnet": { "id": "[variables('subnetRef')]" } } } ] } },
とまあ、こんな具合でそれっぽいテンプレートが出来上がったら、ポータルの [新規] – [テンプレートのデプロイ] に張り付けて、デプロイしてみましょう。(コンピューター名を役割ごとに別で定義したかったので、以下では VM やら NIC、Public IP を 5 台分コピーして定義しています)
大体どっかしら間違っていて、展開前の検証フェーズで失敗すると思います。エラーに表示された内容やキーワードを頼りに、カッコがそろっているか、パラメーターが前後と整合性がとれているかなどを確認しましょう。あとは修正とデプロイを繰り返して、期待したものが出来上がるまで微調整すれば終わりです。
3. 余談
大量の VM を展開する際は、サブスクリプションのクォータに気を付けましょう。足りない場合は引き上げ申請をすればいいんですが、数日~1 週間程度かかるので、急ぎの場合はリージョンを変えればいいと思います。(ARM はリージョン毎にクォーター設定されているので。)
- Microsoft Azure のクォータ増加について
https://blogs.msdn.microsoft.com/dsazurejp/2013/10/22/microsoft-azure/ - Azure サブスクリプションとサービスの制限、クォータ、制約
https://docs.microsoft.com/ja-jp/azure/azure-subscription-service-limits
ちなみに、クォーターはプレビュー ポータル (https://preview.portal.azure.com) のサブスクリプション ブレードから細かく見れるようになっています。(そのうち一般のポータルにも来るはず?)
あと、JSON の編集は Visual Studio もしくは Visual Studio Code を使うとかなり便利です。
- Visual Studio での Azure リソース グループの作成とデプロイ
https://docs.microsoft.com/ja-jp/azure/azure-resource-manager/vs-azure-tools-resource-groups-deployment-projects-create-deploy - Visual Studio Code で Azure Resource Manager テンプレートを操作する
https://docs.microsoft.com/ja-jp/azure/azure-resource-manager/resource-manager-vs-code
そんなこんなで、実質 2 時間くらいで無事デプロイが終わりました。クラウドの時代なので、このくらい片手間でサクっと出来ると便利ですね。業務効率化は正義!
2 comments for “大量の Azure VM を展開してみる”