【问题标题】:ARM - Add multiple VM to Recovery Services Vault (copyIndex)ARM - 将多个 VM 添加到恢复服务库 (copyIndex)
【发布时间】:2017-11-20 17:20:19
【问题描述】:

我正在尝试使用恢复服务,我可以通过 ARM 模板将 VM 自动添加到 Azure 备份。我已在单台机器部署上成功完成此操作,但我正在尝试在部署多个 VM 时导入它。

这是我得到帮助的地方: https://www.francoisdelport.com/2017/03/automating-azure-vm-backups-using-arm-templates/

Azure ARM JSON template - Add VM to Recovery Services Vault in different Resource Group

这是我工作过的单个部署的 sn-p

{
  "apiVersion": "2017-05-10",
  "name": "nestedTemplate",
  "type": "Microsoft.Resources/deployments",
  "resourceGroup": "Env1",
  "dependsOn": [
    "[concat('Microsoft.Compute/virtualMachines/', variables('vmName'))]"
  ],
  "properties": {
    "mode": "Incremental",
    "template": {
      "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
      "contentVersion": "1.0.0.0",
      "parameters": {},
      "variables": {},
      "resources": [
        {
          "apiVersion": "2016-06-01",
          "name": "[concat( parameters('recoveryVault'), '/Azure/', 'iaasvmcontainer;iaasvmcontainerv2;', parameters('vmRsg') , ';', parameters('vmPrefix'), '/vm;iaasvmcontainerv2;', parameters('vmRsg'),';', parameters('vmPrefix'))]",
          "location": "[resourceGroup().location]",
          "type": "Microsoft.RecoveryServices/vaults/backupFabrics/protectionContainers/protectedItems",
          "properties": {
            "protectedItemType": "Microsoft.Compute/virtualMachines",
            "policyId": "[resourceId('Microsoft.RecoveryServices/vaults/backupPolicies', parameters('recoveryVault'), parameters('recoveryPolicy'))]",
            "sourceResourceId": "[resourceId(subscription().subscriptionId, parameters('vmRsg'), 'Microsoft.Compute/virtualMachines', parameters('vmPrefix'))]"
          }
        }
      ]
    }
  }
}

现在我正在尝试以 copyIndex 形式将其用于 VM 部署,这是我一直在测试的代码:

{
  "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "adminUsername": {
      "type": "string",
      "minLength": 1,
      "metadata": {
        "description": "Username for the Virtual Machine."
      }
    },
    "adminPassword": {
      "type": "securestring",
      "metadata": {
        "description": "Password for the Virtual Machine."
      }
    },
    "dnsNameForPublicIP": {
      "type": "string",
      "minLength": 1,
      "metadata": {
        "description": "Globally unique DNS Name for the Public IP used to access the Virtual Machine."
      }
    },
    "windowsOSVersion": {
      "type": "string",
      "defaultValue": "2012-R2-Datacenter",
      "allowedValues": [
        "2008-R2-SP1",
        "2012-Datacenter",
        "2012-R2-Datacenter"
      ],
      "metadata": {
        "description": "The Windows version for the VM. This will pick a fully patched image of this given Windows version. Allowed values: 2008-R2-SP1, 2012-Datacenter, 2012-R2-Datacenter."
      }
    },
    "vmCount": {
      "type": "int",
      "defaultValue": 1
    },
    "virtualNetworkName": {
      "type": "string"
    },
    "dataDiskCount": {
      "type": "int",
      "defaultValue": 1
    },
    "recoveryVault": {
      "type": "string",
      "metadata": {
        "description": "Backup vault name"
      }
    },
    "recoveryPolicy": {
      "type": "string",
      "metadata": {
        "description": "Backcup policy name"
      }
    },
    "vmPrefix": {
      "type": "string",
      "metadata": {
        "description": "Prefix for VM names, used with vmCount to build the VM names"
      }
    },
    "vmRsg": {
      "type": "string",
      "metadata": {
        "description": "Resource group where VMs reside"
      }
    }
  },
  "variables": {
    "imagePublisher": "MicrosoftWindowsServer",
    "imageOffer": "WindowsServer",
    "OSDiskName": "osdiskforwindowssimple",
    "nicName": "myVMNic",
    "subnetName": "Subnet",
    "vhdStorageType": "Standard_LRS",
    "publicIPAddressName": "myPublicIP",
    "publicIPAddressType": "Dynamic",
    "vhdStorageContainerName": "vhds",
    "vmName": "MWindowsVM",
    "vmSize": "Standard_A2",
    "virtualNetworkName": "MyVNET",
    "vnetId": "[resourceId(resourceGroup().name, 'Microsoft.Network/virtualNetworks', parameters('virtualNetworkName'))]",
    "subnetRef": "[concat(variables('vnetId'), '/subnets/', variables('subnetName'))]"
  },
  "resources": [
    {
      "apiVersion": "2016-03-30",
      "type": "Microsoft.Network/publicIPAddresses",
      "name": "[concat(variables('publicIPAddressName'), copyIndex(1))]",
      "location": "[resourceGroup().location]",
      "tags": {
        "displayName": "PublicIPAddress"
      },
      "properties": {
        "publicIPAllocationMethod": "[variables('publicIPAddressType')]",
        "dnsSettings": {
          "domainNameLabel": "[concat(parameters('dnsNameForPublicIP'), copyIndex(1))]"
        }
      },
      "copy": {
        "name": "publicIpCopy",
        "count": "[parameters('vmCount')]"
      }
    },
    {
      "apiVersion": "2016-03-30",
      "type": "Microsoft.Network/networkInterfaces",
      "name": "[concat(variables('nicName'), copyIndex(1))]",
      "location": "[resourceGroup().location]",
      "tags": {
        "displayName": "NetworkInterface"
      },
      "dependsOn": [
        "[concat('Microsoft.Network/publicIPAddresses/', concat(variables('publicIPAddressName'), copyIndex(1)))]"
      ],
      "properties": {
        "ipConfigurations": [
          {
            "name": "[concat('ipconfig', copyIndex(1))]",
            "properties": {
              "privateIPAllocationMethod": "Dynamic",
              "publicIPAddress": {
                "id": "[resourceId('Microsoft.Network/publicIPAddresses', concat(variables('publicIPAddressName'), copyIndex(1)))]"
              },
              "subnet": {
                "id": "[variables('subnetRef')]"
              }
            }
          }
        ]
      },
      "copy": {
        "name": "nicCopy",
        "count": "[parameters('vmCount')]"
      }
    },
    {
      "apiVersion": "2017-03-30",
      "copy": {
        "name": "nodeCopy",
        "count": "[parameters('vmCount')]"
      },
      "type": "Microsoft.Compute/virtualMachines",
      "name": "[concat(variables('vmName'), copyIndex(1))]",
      "location": "[resourceGroup().location]",
      "tags": {
        "displayName": "VirtualMachine"
      },
      "dependsOn": [
        "[resourceId('Microsoft.Network/networkInterfaces/', concat(variables('nicName'), copyIndex(1)))]"
      ],
      "properties": {
        "hardwareProfile": {
          "vmSize": "[variables('vmSize')]"
        },
        "osProfile": {
          "computerName": "[concat(variables('vmName'), copyIndex(1))]",
          "adminUsername": "[parameters('adminUsername')]",
          "adminPassword": "[parameters('adminPassword')]"
        },
        "storageProfile": {
          "imageReference": {
            "publisher": "[variables('imagePublisher')]",
            "offer": "[variables('imageOffer')]",
            "sku": "[parameters('windowsOSVersion')]",
            "version": "latest"
          },
          "osDisk": {
            "createOption": "FromImage"
          },
          "copy": [
            {
              "name": "dataDisks",
              "count": "[parameters('dataDiskCount')]",
              "input": {
                "diskSizeGB": 1023,
                "lun": "[copyIndex('dataDisks')]",
                "createOption": "Empty"
              }
            }
          ]
        },
        "networkProfile": {
          "networkInterfaces": [
            {
              "id": "[resourceId('Microsoft.Network/networkInterfaces', concat(variables('nicName'), copyIndex(1)))]"
            }
          ]
        }
      }
    },
    {
      "apiVersion": "2017-05-10",
      "name": "nestedTemplate",
      "type": "Microsoft.Resources/deployments",
      "resourceGroup": "Env1",
      "dependsOn": [
        "[concat('Microsoft.Compute/virtualMachines/', concat(variables('vmName'), copyIndex(1)))]"
      ],
      "properties": {
        "mode": "Incremental",
        "template": {
          "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
          "contentVersion": "1.0.0.0",
          "parameters": {},
          "variables": {},
          "resources": [
            {
              "copy": {
                "name": "protectedItemsCopy",
                "count": "[parameters('vmCount')]"
              },
              "apiVersion": "2017-03-30",
              "name": "[concat( parameters('recoveryVault'), '/Azure/', 'iaasvmcontainer;iaasvmcontainerv2;', parameters('vmRsg') , ';', parameters('vmPrefix'), copyIndex(1), '/vm;iaasvmcontainerv2;', parameters('vmRsg'),';', parameters('vmPrefix'), copyIndex(1))]",
              "location": "[resourceGroup().location]",
              "type": "Microsoft.RecoveryServices/vaults/backupFabrics/protectionContainers/protectedItems",
              "properties": {
                "protectedItemType": "Microsoft.Compute/virtualMachines",
                "policyId": "[resourceId('Microsoft.RecoveryServices/vaults/backupPolicies', parameters('recoveryVault'), parameters('recoveryPolicy'))]",
                "sourceResourceId": "[resourceId(subscription().subscriptionId ,parameters('vmRsg'),'Microsoft.Compute/virtualMachines', concat(parameters('vmPrefix'), copyIndex(1)) )]"
              }
            }
          ]
        }
      }
    }
  ]
}

不幸的是,它在尝试部署时报告了一个错误,我不知道为什么,因为它似乎是正确的。

Error: Code=InvalidTemplate; Message=Deployment template validation failed: 'The template resource 'nestedTemplate' at line '198' and column '10' is not valid: The template function 'copyIndex' is not expected at this location. The function can only be used in a resource with copy specified. Please see https://aka.ms/arm-copy for usage details.. Please see https://aka.ms/arm-template-expressions for usage details.'.
The deployment validation failed

仅供参考,第 198 行是 "name": "nestedTemplate",

有什么想法吗?

【问题讨论】:

    标签: azure templates azure-resource-manager


    【解决方案1】:

    为了扩展@4c74356b41 的答案,我错过了父模板上"Microsoft.Resources/deployments" 中所有重要的"index":{ "value": "[copyIndex()]"

    想了解更多的朋友可以看看:https://docs.microsoft.com/en-us/azure/azure-resource-manager/resource-group-create-multiple

    确保在需要复制的项目旁边有('index') 参数,例如"[concat(parameters('WHATEVER'), parameters('index'))]"

    我最后还在我的链接模板中有一个嵌套源代码,用于我正在寻找的整体设计。

    所以我的父模板有一个链接(子)模板(到另一个文件):

    name": "[concat('nestings', copyIndex(1))]",
    "type": "Microsoft.Resources/deployments", ...
    

    我的子模板具有 VM 的所有常用建筑物,参数为 ('index'),以确保正确命名重复的项目。

    最后在子模板的底部我有一个嵌套的模板源,这样我就可以将 VM 备份到另一个资源组(必须嵌套,否则你不能做多个资源组),看起来像这样:

    {
          "apiVersion": "2017-05-10",
          "name": "[concat('nestedTemplate', parameters('index'))]",
          "type": "Microsoft.Resources/deployments",
          "resourceGroup": "Env1",
          "dependsOn": [
            "[concat('Microsoft.Compute/virtualMachines/', concat(variables('vmName'), parameters('index')))]"
          ],
          "properties": {
            "mode": "Incremental",
            "template": {
              "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
              "contentVersion": "1.0.0.0",
              "parameters": {},
              "variables": {},
              "resources": [
                {
                  "apiVersion": "2016-06-01",
                  "name": "[concat( parameters('recoveryVault'), '/Azure/', 'iaasvmcontainer;iaasvmcontainerv2;', parameters('vmRsg') , ';', concat(parameters('vmPrefix'), parameters('index')), '/vm;iaasvmcontainerv2;', parameters('vmRsg'),';', concat(parameters('vmPrefix'), parameters('index')))]",
                  "location": "[resourceGroup().location]",
                  "type": "Microsoft.RecoveryServices/vaults/backupFabrics/protectionContainers/protectedItems",
                  "properties": {
                    "protectedItemType": "Microsoft.Compute/virtualMachines",
                    "policyId": "[resourceId('Microsoft.RecoveryServices/vaults/backupPolicies', parameters('recoveryVault'), parameters('recoveryPolicy'))]",
                    "sourceResourceId": "[resourceId(subscription().subscriptionId, parameters('vmRsg'), 'Microsoft.Compute/virtualMachines', concat(parameters('vmPrefix'), parameters('index')))]"
                  }
                }
              ]
            }
          }
        }
    

    【讨论】:

      【解决方案2】:

      那么它告诉你你不应该在那个地方使用 copyIndex() 函数。现在我不知道为什么会发生这种情况,但我知道内联模板是一团糟(例如,它们使用父模板参数,而不是嵌套模板),我很确定你是否将该模板转换为真正的嵌套模板模板(所以一个链接的模板,完全独立的文件)上面的语法可以工作。

      另外,我正在以单独的方式处理此问题。我为每个 VM 使用 1 个单一嵌套​​部署,因此我在部署资源上使用副本,而不是备份资源。

      【讨论】:

      • 您是否在"Microsoft.Resources/deployments" 上使用copyIndex 用于嵌套或链接模板?我找不到链接模板的示例(也没有编译)"copy",只有嵌套(遗憾的是我需要为我正在创建的整个模板链接)。
      • 好吧,取决于你叫什么。我将嵌套模板称为使用链接执行的模板(因此不是内联的)。和副本完全没问题。另外,你最后一句话毫无意义。显然,你不能让它按照你想要的方式工作。
      猜你喜欢
      • 2019-04-30
      • 1970-01-01
      • 2019-04-19
      • 1970-01-01
      • 1970-01-01
      • 2014-10-08
      • 2017-05-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多