【发布时间】:2019-10-25 13:28:00
【问题描述】:
我已经开发了 ARM 模板,可以并行构建多个虚拟机。每台机器都有一个 OS 磁盘和一个 vNIC。我可以使用 PowerShell 部署 ARM 模板,也可以上传 ARM 模板并使用 Azure 门户的“部署自定义模板”功能进行部署。
但是,我似乎无法完全正确地使用复制循环将语法添加到 JsonADDomainExtension 中,以便将所有机器都添加到同一模板中的我的域中。
目前我所有的资源都在一个资源组中。我已经预先部署了一个带有子网和存储帐户的 vNET。
以下是可同时部署多台机器的 ARM 模板。
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters":
{
"adminUsername":
{
"type": "string",
"metadata": {"description": "Administrator username for the Virtual Machine."}
},
"adminPassword":
{
"type": "securestring",
"metadata": {"description": "Password for the Virtual Machine.Should contain any 3 of: 1 Lower Case, 1 Upper Case, 1 Number and 1 Special character."}
},
"numberOfInstances":
{
"type": "int",
"defaultValue": 3,
"minValue": 2,
"maxValue": 5,
"metadata": {"description": "Number of VMs to deploy, limit 5 since this sample is using a single storage account."}
},
"StartOfCount":
{
"type": "int",
"defaultValue": 1,
"metadata": {"description": "Number that you want to start the machine name numbering from, EG to create 5 VMs with the name starting at 045 (W2016SRV-045-vm) you would enter 45 here, or to start at 1 just enter 1 here, this wil give you a machine name like 'W2016SRV-001-vm'."}
},
"vmNamePrefix":
{
"type": "string",
"defaultValue": "W2016SRV-",
"maxLength": 9,
"metadata": {"description": "The VM name prefix maximum 9 characters. This allows for three digits in the name and trailing '-vm'. EG: 'W2016SRV-045-vm'."}
},
"vmSize":
{
"type": "string",
"defaultValue": "Standard_B2ms",
"metadata":
{
"description": "The size(T-shirt) for the VM. (Standard_D8s_v3)",
"SNC::Parameter::Metadata": {"referenceType": "Microsoft.Compute/virtualMachines/vmSize"}
}
},
"vmLocation":
{
"type": "string",
"defaultValue": "AustraliaSoutheast",
"metadata":
{
"description": "Location or datacenter where the VM will be placed.",
"SNC::Parameter::Metadata": {"referenceType": "Microsoft.Azure/region"}
}
},
"domainToJoin":
{
"type": "string",
"metadata": {"description": "The FQDN of the AD domain"}
},
"domainUsername":
{
"type": "string",
"metadata": {"description": "Username of the account on the domain"}
},
"domainPassword":
{
"type": "securestring",
"metadata": {"description": "Password of the account on the domain"}
},
"ouPath":
{
"type": "string",
"metadata": {"description": "Specifies an organizational unit (OU) for the domain account. Enter the full distinguished name of the OU in quotation marks. Example: 'OU=testOU; DC=domain; DC=Domain; DC=com"}
},
"sizeOfDiskInGB":
{
"type": "int",
"defaultValue": 200,
"metadata": {"description": "The disk size for the OS drive in the VM, in GBs. Default Value is 500"}
},
"existingBootDiagStorageResourceGroup":
{
"type": "string",
"metadata": {"description": "Storage account resource group name where boot diagnistics will be stored"}
},
"existingBootDiagStorageName":
{
"type": "string",
"metadata":
{
"description": "Storage account name where boot diagnistics will be stored. It should be at the same location as the VM.",
"SNC::Parameter::Metadata": {"referenceType": "Microsoft.Storage/storageAccounts"}
}
},
"existingvNetResourceGroup":
{
"type": "string",
"metadata":
{
"description": "Resource Group of the Existing Virtual Network.",
"SNC::Parameter::Metadata": {"referenceType": "Microsoft.Resources/resourceGroups"}
}
},
"existingvNetName":
{
"type": "string",
"metadata":
{
"description": "Existing Virtual Network to connect to Network Interface to.It should be at the same location as the VM.",
"SNC::Parameter::Metadata": {"referenceType": "Microsoft.Network/virtualNetworks"}
}
},
"subnetName":
{
"type": "string",
"metadata":
{
"description": "The Subnet for the VM.",
"SNC::Parameter::Metadata": {"referenceType": "Microsoft.Network/subNets"}
}
}
},
"variables":
{
"storageAccountType": "Standard_LRS",
"vnetID": "[resourceId(parameters('existingvNetResourceGroup'), 'Microsoft.Network/virtualNetworks', parameters('existingvNetName'))]",
"subnetRef": "[concat(variables('vnetID'),'/subnets/', parameters('subnetName'))]",
"StartOfCountString": "[String(Parameters('StartOfCount'))]"
},
"resources":
[
{
"apiVersion": "[providers('Microsoft.Network','networkInterfaces').apiVersions[0]]",
"type": "Microsoft.Network/networkInterfaces",
"name": "[concat(parameters('vmNamePrefix'), padLeft(copyIndex(parameters('StartOfCount')),3, '0'), '-vm-vNic')]",
"location": "[parameters('vmLocation')]",
"copy": {
"name": "nicLoop",
"count": "[parameters('numberOfInstances')]"
},
"properties":
{
"ipConfigurations":
[
{
"name": "Prod",
"properties":
{
"privateIPAllocationMethod": "Dynamic",
"subnet": {"id": "[variables('subnetRef')]"}
}
}
]
}
},
{
"apiVersion": "[providers('Microsoft.Compute','virtualMachines').apiVersions[0]]",
"type": "Microsoft.Compute/virtualMachines",
"name": "[concat(parameters('vmNamePrefix'), padLeft(copyIndex(parameters('StartOfCount')),3, '0'), '-vm')]",
"location": "[parameters('vmLocation')]",
"copy": {
"name": "vmLoop",
"count": "[parameters('numberOfInstances')]"
},
"dependsOn": ["nicLoop"],
"tags":
{
"Project": "***"
},
"properties":
{
"hardwareProfile": {"vmSize": "[parameters('vmSize')]"},
"osProfile":
{
"computerName": "[concat(parameters('vmNamePrefix'), padLeft(copyIndex(parameters('StartOfCount')),3, '0'), '-vm')]",
"adminUsername": "[parameters('adminUsername')]",
"adminPassword": "[parameters('adminPassword')]",
"windowsConfiguration": {"enableAutomaticUpdates": false}
},
"storageProfile":
{
"imageReference": {
"id": "/subscriptions/***/resourceGroups/***/providers/Microsoft.Compute/images/***"
},
"osDisk":
{
"name": "[concat(parameters('vmNamePrefix'), padLeft(copyIndex(parameters('StartOfCount')),3, '0'), '-vm-osDisk')]",
"createOption": "FromImage",
"diskSizeGB": "[parameters('sizeOfDiskInGB')]",
"caching": "ReadWrite",
"managedDisk": {"storageAccountType": "[variables('storageAccountType')]"}
}
},
"networkProfile": {"networkInterfaces": [{"id": "[resourceId('Microsoft.Network/networkInterfaces',concat(parameters('vmNamePrefix'), padLeft(copyIndex(parameters('StartOfCount')),3, '0'), '-vm-vNic'))]"}]},
"diagnosticsProfile":
{
"bootDiagnostics":
{
"enabled": true,
"storageUri": "[reference(resourceId(parameters('existingBootDiagStorageResourceGroup'), 'Microsoft.Storage/storageAccounts', parameters('existingBootDiagStorageName')), '2015-06-15').primaryEndpoints['blob']]"
}
}
}
}
]
}
但是,如果我将此添加到底部的资源位中,则它不起作用。
{
"apiVersion": "2016-03-30",
"type": "Microsoft.Compute/virtualMachines/extensions",
"name": "[concat(parameters('vmNamePrefix'), padLeft(copyIndex(variables('StartOfCountString')),3, '0'), '/JoinDomain')]",
"location": "[resourceGroup().location]",
"copy": {
"name": "DomainJoinLoop",
"count": "[parameters('numberOfInstances')]"
},
"dependsOn": "[concat('Microsoft.Compute/virtualMachines/', concat(parameters('vmNamePrefix'), padLeft(copyIndex(variables('StartOfCountString')),3, '0')))]",
"properties": {
"publisher": "Microsoft.Compute",
"type": "JsonADDomainExtension",
"typeHandlerVersion": "1.3",
"autoUpgradeMinorVersion": true,
"settings": {
"Name": "[parameters('domainToJoin')]",
"User": "[concat(parameters('domainToJoin'), '\\', parameters('domainUsername'))]",
"OUPath": "[parameters('ouPath')]",
"Restart": "true",
"Options": "3"
},
"protectedsettings": {
"Password": "[parameters('domainPassword')]"
}
}
}
在代码的 copyIndex 部分,我尝试了变量和参数来设置 copyIndex 的偏移量。我也尝试过硬编码。我不断收到这样的错误。
{"telemetryId":"649e0a7f-2c22-41f9-bede-c13618f5053a", "bladeInstanceId":"Blade_b45c7efadff74340820345aa2e9d76c1_26_0", “galleryItemId”:“Microsoft.Template”,“createBlade”:“DeployToAzure”, "code":"InvalidRequestContent", "message":"请求内容是 无效且无法反序列化:'错误转换值 \"[concat('Microsoft.Compute/virtualMachines/', 连接(参数('vmNamePrefix'), padLeft(copyIndex(variables('StartOfCountString')),3, '0')))]\" 到 键入“System.String[]”。小路 'properties.template.resources[1].resources[0].dependsOn',第 259 行, 位置 171.'."}
我想为复制索引设置偏移量的原因是我可以构建十台机器,例如 W2016SRV-001、002、... 010,然后从 011、012 开始构建更多机器, 013等
还有其他方法可以解决它,但我真的希望能够在 ARM 模板中执行此操作,并且在我进行大量谷歌搜索之后我还不知道为什么它不应该是可能的。
.................................................. ....................
好的,按照@4c74356b41 的建议编辑模板后,当我尝试通过门户部署模板时,我现在遇到了一个全新的不同错误。
{"telemetryId":"649e0a7f-2c22-41f9-bede-c13618f5053a",
"bladeInstanceId":"Blade_b45c7efadff74340820345aa2e9d76c1_26_0",
"galleryItemId":"Microsoft.Template","createBlade":"DeployToAzure",
"code":"InvalidTemplate",
"message":"Deployment template validation failed: 'The template resource
'[concat(parameters('vmNamePrefix'), padLeft(copyIndex(parameters('StartOfCount')),3, '0'),
'-vm/JoinDomain')]'
at line '250' column '13' is not valid. Copying nested resources is not supported.
Please see https://aka.ms/arm-copy/#looping-on-a-nested-resource for usage details.'."}
因此,按照错误消息中的链接并阅读更多内容......我需要做的是将域加入扩展作为 VM 的子级删除,并将其作为顶级资源。呜呜呜成功了。
所以现在我的 ARM 模板的结尾看起来像这样。
*** VM bits are here ***
}
}
}, <-- end of the VM bits.
{
"apiVersion": "2016-03-30",
"type": "Microsoft.Compute/virtualMachines/extensions",
"name": "[concat(parameters('vmNamePrefix'), padLeft(copyIndex(parameters('StartOfCount')),3, '0'), '-vm/JoinDomain')]",
"location": "[resourceGroup().location]",
"copy": {
"name": "DomainJoinLoop",
"count": "[parameters('numberOfInstances')]"
},
"dependsOn": [ "vmLoop" ],
"properties":
{
"publisher": "Microsoft.Compute",
"type": "JsonADDomainExtension",
"typeHandlerVersion": "1.3",
"autoUpgradeMinorVersion": true,
"settings":
{
"Name": "[parameters('domainToJoin')]",
"User": "[concat(parameters('domainToJoin'), '\\', parameters('domainUsername'))]",
"OUPath": "[parameters('ouPath')]",
"Restart": "true",
"Options": "3"
},
"protectedsettings": {"Password": "[parameters('domainPassword')]"}
}
}
],
"outputs":
{}
}
并行部署的多个虚拟机,并且全部加入域都没有问题。
所以我的经验教训就是这些,我希望它们在未来对其他人有所帮助。
- 您不能对子资源使用 copyIndex。
- 确保正确命名 DomainJoin 扩展。
【问题讨论】:
-
谢谢。它有帮助,但为什么扩展没有指定每个扩展部署到的 VM?
标签: azure azure-resource-manager arm-template