Ошибка с JsonADDomainExtension и копирование цикла - PullRequest
0 голосов
/ 11 июня 2019

Я разработал и ARM Template, который будет строить несколько виртуальных машин параллельно.На каждой машине есть диск ОС и виртуальный сетевой адаптер.Я могу использовать 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_b45c7efadff74340820345aa2e9dIt""," createBlade ":" DeployToAzure "," code ":" InvalidRequestContent "," message ":" Содержимое запроса было недопустимым и не может быть десериализовано: 'Ошибка преобразования значения \ "[concat (' Microsoft.Compute / virtualMachines /', concat (параметры (' vmNamePrefix ')), padLeft (copyIndex (переменные (' StartOfCountString ')), 3,' 0 ')))] \ "для типа' System.String [] '. Path' properties.template.resources [1] .resources [0] .dependsOn ', строка 259, позиция 171.'. "}

Причина, по которой я хочу установить смещение для индекса копирования, заключается в том, что я могусборка, скажем, десять машин, таких как W2016SRV-001, 002, ... 010, а затем сборка других машин, начиная с 011, 012, 013 и т. д.

Есть и другие способы, но я очень хочубыть в состоянии сделать это в шаблоне ARM, и я еще не знаю, после всех моих допбездействующий поиск в Google, почему это не должно быть возможно.

...............................................................................

ОК, поэтому после редактирования шаблона, как предложено @ 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.'."}

Итак, перейдя по ссылке в ошибкесообщение и чтение еще ... что мне нужно было сделать, это исключить расширение присоединения к домену как дочерний элемент виртуальной машины и использовать его в качестве ресурса верхнего уровня.Woot woot это сработало.

Итак, теперь конец моего 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":
    {}
}

Несколько виртуальных машин развернуты параллельно и все без проблем подключены к домену.

оооочень мои извлеченные уроки таковы, и я надеюсь, что они помогут кому-то еще в будущем.

  1. Вы не можете использовать copyIndex на дочернем ресурсе.
  2. Убедитесь, что вы назвали свойРасширение DomainJoin правильно.

1 Ответ

0 голосов
/ 11 июня 2019

Сравните ваше имя и расширение vm:

concat(parameters('vmNamePrefix'), padLeft(copyIndex(parameters('StartOfCount')),3, '0'), '-vm')
concat(parameters('vmNamePrefix'), padLeft(copyIndex(variables('StartOfCountString')),3, '0'), '/JoinDomain')

, кроме того факта, что вы используете ненужную переменную, которую вы пропускаете -vm.Имя расширения должно быть в формате parent_name/extension_name, иначе не будет известно, к какому родительскому ресурсу относится это расширение (оно всегда должно принадлежать какому-либо виртуальному компьютеру).

Ваш dependsOn также неверен, выможно упростить до этого:

"dependsOn": [ "vmLoop" ]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...