wake-up-neo.com

Kann ich eine haben? ARM Vorlagenressource mit einem COPY-Array von N

Ich implementiere eine Vorlage ARM, die einen Kopierressourcenblock verwendet, um eine oder mehrere Datenfestplatten auf einer VM bereitzustellen. Was ich gerne tun würde, ist dies auf 0 oder mehr zu ändern. 

Der Parameter, den ich verwende, ist 

    "VirtualMachineDiskSizeArray": {
        "type": "array",
        "defaultValue": [ "100" ]
    },

Welches wird dann in einer Ressource aufgerufen:

   "resources": [
    {
        "name": "[parameters('virtualMachineName')]",
        "type": "Microsoft.Compute/virtualMachines",
        "apiVersion": "2016-04-30-preview",
        "location": "[parameters('rgLocation')]",
        "dependsOn": [
            "[concat('Microsoft.Storage/storageAccounts/', parameters('rgStorageAccountName'))]"
        ],
        "properties": {
            "osProfile": { ... },
            "hardwareProfile": { ... },
            "storageProfile": {
                "imageReference": { ... },
                "osDisk": { ... },
                "copy": [
                    {
                        "name": "dataDisks",
                        "count": "[length(parameters('VirtualMachineDiskSizeArray'))]",
                        "input": {
                            "lun": "[copyIndex('dataDisks')]",
                            "name": "[concat(parameters('vmDataDiskNameStub'), add(copyIndex('dataDisks'),1), '.vhd')]",
                            "diskSizeGB": "[parameters('VirtualMachineDiskSizeArray')[copyIndex('dataDisks')]]",
                            "createOption": "Empty",
                            "vhd": {
                                "uri": "[concat(concat(reference(resourceId(parameters('rgName'), 'Microsoft.Storage/storageAccounts', parameters('rgStorageAccountName')), '2015-06-15').primaryEndpoints['blob'], 'vhds/'), concat(parameters('vmDataDiskNameStub'),  add(copyIndex('dataDisks'),1), '.vhd') )]"
                            }
                        }
                    }
                ]
            }
        }
    },

Wenn ich jedoch ein Array von Datenplatten mit 0 Elementen übergeben werde, erhalte ich diesen Fehler wie erwartet:

Validation returned the following errors:
: Deployment template validation failed: 'The template 'copy' definition at line '0' and column '0' has an invalid copy count. The co
py count must be a postive integer value and cannot exceed '800'. Please see https://aka.ms/arm-copy for usage details.'.

Template is invalid.

Ich möchte versuchen, dies irgendwie zu umgehen - ich habe versucht, eine Bedingung in die Kopie einzufügen: 

"condition": "[  greater(length(parameters('VirtualMachineDiskSizeArray')), 0)]",

Aber das gab den gleichen Fehler zurück.

Ich erforsche verschachtelte Vorlagen, aber das sieht für einen section einer Ressource nicht gut aus.

Dies lässt sich am einfachsten umgehen, indem Sie Folgendes verwenden:

{
    "condition": "[if(equals(parameters('numberOfDataDisks'), 0), bool('false'), bool('true'))]",
    "apiVersion": "2017-03-30",
    "type": "Microsoft.Compute/virtualMachines",
    "name": "[variables('vmName')]",
    "location": "[resourceGroup().location]",
    "properties": {
        "storageProfile": {
            "imageReference": { xxx },
            "osDisk": { xxx },
            "copy": [
                {
                    "name": "dataDisks",
                    "count": "[if(equals(parameters('numberOfDataDisks'), 0), 1, parameters('numberOfDataDisks'))]",
                    "input": {
                        "diskSizeGB": "1023",
                        "lun": "[copyIndex('dataDisks')]",
                        "createOption": "Empty"
                    }
                }
            ]
        }
    }
}

dies wird die Tatsache umgehen, dass Sie 0 Datenträger übergeben und diese VM nicht gleichzeitig bereitstellen. Sie müssen lediglich eine weitere VM-Ressource hinzufügen. Es muss jedoch einen anderen Namen haben (andernfalls schlägt die Vorlage fehl), oder Sie können eine verschachtelte Vorlage verwenden, um eine VM mit demselben Namen bereitzustellen.

dies kann durch kürzlich vorgenommene Korrekturen an der Funktion if() verbessert werden. Sie können dies auch umgehen, indem Sie geschachtelte Bereitstellungen verwenden

8
4c74356b41

Im Interest of Time habe ich meine Herangehensweise geändert, mag es aber nicht wirklich ... 

Ich habe jetzt zwei Json-Dateien, VMDeploy.json und VMDeploy-NoDataDisks.json.

Sie sind identisch mit dem Abschnitt storageProfile der Ressource VM:

VMDeploy.json:

"storageProfile": {
  "imageReference": { ... },
  "osDisk": { ... },
  "copy": [
    {
    "name": "dataDisks",
    "count": "[length(parameters('VirtualMachineDiskSizeArray'))]",
    "input": {
      "lun": "[copyIndex('dataDisks')]",
      "name": "[concat(parameters('vmDataDiskNameStub'), add(copyIndex('dataDisks'),1), '.vhd')]",
      "diskSizeGB": "[parameters('VirtualMachineDiskSizeArray')[copyIndex('dataDisks')]]",
      "createOption": "Empty",
      "vhd": {
        "uri": "[concat(concat(reference(resourceId(parameters('rgName'), 'Microsoft.Storage/storageAccounts', parameters('rgStorageAccountName')), '2015-06-15').primaryEndpoints['blob'], 'vhds/'), concat(parameters('vmDataDiskNameStub'),  add(copyIndex('dataDisks'),1), '.vhd') )]"
        }
      }
    }
  ]
}

VMDeploy-NoDataDisks.json:

"storageProfile": {
  "imageReference": { ... },
  "osDisk": { ... },
  "dataDisks": []
}

Und ich habe einen Powershell-Block zwischen den beiden Json-Dateien:

if ($DriveArray.Count -eq 0) {
    $TemplateFile = $TemplateFile.Replace('.json','-NoDataDisks.json')
}

Ich werde diese Antwort verwenden, um einen Verweis auf meine Forschung in verschachtelten Vorlagen zu verwenden.

Wenn ich hier sehe, sehe ich einen Ansatz, der zwei verschachtelte Vorlagen hätte, eine davon wie folgt:

"resources": [
{
    "name": "MultiDataDisk",
    "type": "Microsoft.Compute/virtualMachines",
    "apiVersion": "2016-04-30-preview",
    "location": "[parameters('rgLocation')]",
    "dependsOn": [
        "[concat('Microsoft.Storage/storageAccounts/', parameters('rgStorageAccountName'))]"
    ],
    "properties": {
        "osProfile": { ... },
        "hardwareProfile": { ... },
        "storageProfile": {
            "imageReference": { ... },
            "osDisk": { ... },
            "copy": [
                {
                    "name": "dataDisks",
                    "count": "[length(parameters('VirtualMachineDiskSizeArray'))]",
                    "input": {
                        "lun": "[copyIndex('dataDisks')]",
                        "name": "[concat(parameters('vmDataDiskNameStub'), add(copyIndex('dataDisks'),1), '.vhd')]",
                        "diskSizeGB": "[parameters('VirtualMachineDiskSizeArray')[copyIndex('dataDisks')]]",
                        "createOption": "Empty",
                        "vhd": {
                            "uri": "[concat(concat(reference(resourceId(parameters('rgName'), 'Microsoft.Storage/storageAccounts', parameters('rgStorageAccountName')), '2015-06-15').primaryEndpoints['blob'], 'vhds/'), concat(parameters('vmDataDiskNameStub'),  add(copyIndex('dataDisks'),1), '.vhd') )]"
                        }
                    }
                }
            ]
        }
    }
}
]

und eins davon:

"resources": [
{
    "name": "ZeroDataDisk",
    "type": "Microsoft.Compute/virtualMachines",
    "apiVersion": "2016-04-30-preview",
    "location": "[parameters('rgLocation')]",
    "dependsOn": [
        "[concat('Microsoft.Storage/storageAccounts/', parameters('rgStorageAccountName'))]"
    ],
    "properties": {
        "osProfile": { ... },
        "hardwareProfile": { ... },
        "storageProfile": {
            "imageReference": { ... },
            "osDisk": { ... },
             "dataDisks": []
        }
    }
}
] 

Und referenzieren Sie sie von einer übergeordneten Vorlage: 

"parameters": {
 "nestedType": {
  "type": "string",
  "defaultValue": "ZeroDataDisk",
  "allowedValues": [
   "ZeroDataDisk",
   "MultiDataDisk"
  ],
 }
},
"resources": [
 {
 "name": "[concat("nested-",parameters('virtualMachineName')]",
 "type": "Microsoft.Resources/deployments",
 "apiVersion": "2015-01-01",
 "properties": {
  "mode": "Incremental",
  "templateLink": {
   "uri": "[concat('https://someplace.on.the.internet/nested/',parameter('nestedType'),".json")],
   "contentVersion": "1.0.0.0"
   },
   "parameters": {
    "rgStorageAccountName": {
     "value": "[parameters(rgStorageAccountName)]"
    },
    "OtherParms": {
     "value": "[parameters('otherParms')]"
    }
     . . .
  }
 }
]
}

Ich glaube jedoch nicht, dass dies besser/einfacher ist als das, was ich in meiner "Interest of Time" -Antwort getan habe, weil

  1. Der Abschnitt, an dem ich interessiert bin (dataDisks), ist von einer Reihe anderer Json umgeben, die nicht ändern, was mich zu dem seltsamen Problem macht, den Code manuell zwischen zwei Dateien zu synchronisieren.
  2. Ich muss jetzt nicht nur zwei Json-Dateien für die verschachtelten Ressourcen verwalten, sondern sie muss über eine öffentlich zugängliche URL veröffentlicht werden.

Wenn ich also keine Kopie von 0-N eines Abschnitts (anstatt von 1-N) oder nur einen Abschnitt verschachteln kann, scheint mein Zwei-Datei-Hack mit dem Powershell-Switch der geringste Aufwand zu sein.

In Bezug auf die Diskettengröße kann ich Ihnen helfen. Was ich tatsächlich getan habe, ist ein Verweis auf eine JSON-Vorlagendatei, in der Größe, Name und Zwischenspeicherung für die Plattenerstellung definiert sind.

Diese können leicht in die Bereitstellung geparst werden

"storageProfile": {
      "copy": [{
        "name": "dataDisks",
        "count": "[length(parameters('dataDiskArray'))]",
        "input": {
          "name": "[concat(parameters('vmName'), if(less(copyindex(1), 10), concat('0', copyindex(1)), concat(copyindex(1))), '-datadisk-', parameters('dataDiskArray')[copyIndex('dataDisks')].name)]",
          "diskSizeGB": "[parameters('dataDiskArray')[copyIndex('dataDisks')].size]",
          "caching": "[parameters('dataDiskArray')[copyIndex('dataDisks')].cache]",
          "lun": "[copyIndex('dataDisks')]",
          "createOption": "Empty"
        }
      }],

Das Problem ist weiterhin Teil der Bereitstellung von VM. Wenn Sie einen VM ohne zusätzliche Festplatten bereitstellen möchten, besteht keine Option zum Auswählen eines Nullwerts.

Ich habe versucht, die Datenträgererstellung in den Variablenabschnitt der Vorlage zu verschieben, aber es ist nicht möglich, VMName als Teil des Namens der Datenträger zu verwenden, die Sie erstellen möchten. Dies liegt daran, dass die Kopierschleife für VM noch nicht initialisiert ist und daher den falschen Namen angibt.

0
user9860446

Ich möchte gerne unsere lösungsbasierten Antworten auf die Antworten geben. Dies ist ein einfaches Beispiel, um ein Eingabearray von Datenträgern (Werte in ihrer Größe) zu erstellen und zusammen mit denen mit Ihrer virtuellen Maschine zu erstellen. arbeitet von 0-n. n muss kleiner sein als unterstützte Festplatten mit der Größe VM und anderen Azure-Grenzwerten :) Dies sollte auch bei diesem Kommentar helfen.

{
    "$schema": "http://schema.management.Azure.com/schemas/2015-01-01/deploymentTemplate.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {
        [...]
        "dataDiskArray": {
            "type": "array",
            "defaultValue": [
                "100",
                "50"
            ]
        }
    },
    "variables": {
        "copy": [
            {
                "name": "dataDisks",
                "count": "[if(equals(length(parameters('dataDiskArray')),0),1, length(parameters('dataDiskArray')))]",
                "input": {
                    "lun": "[if(equals(length(parameters('dataDiskArray')),0),0, copyIndex('dataDisks'))]",
                    "createOption": "Empty",
                    "diskSizeGB": "[if(equals(length(parameters('dataDiskArray')),0),10,parameters('dataDiskArray')[copyIndex('dataDisks')])]"
                }
            }
        ]
    },
    "resources": [
        {
            "name": "[parameters('virtualMachineName')]",
            "type": "Microsoft.Compute/virtualMachines",
            [...]
            "properties": {
                [...]
                "storageProfile": {
                    [...]
                    "dataDisks": "[if(equals(length(parameters('dataDiskArray')),0),json('null'),variables('dataDisks'))]"
                },
                [...]
                }
            }
    ],
    "outputs": {
    }
}
0
Klaas

Arbeitsprobe https://github.com/mariuszdotnet/Azure-resource-manager-tutorial/blob/master/azuredeploy.json

Hier ist die Zusammenfassung:

  • Verschieben Sie die Festplatten in eine Variable und verwenden Sie die variable Iteration.
  • Wenn numDisks = 0, dann ist diskLoop = 1 (dies verhindert einen Fehler beim Kopieren von Variablen)
  • Erstellen Sie ein variables Kopierobjekt mit count = diskLoop
"copy": [
  {
      "name": "dataDisks",
      "count": "[if(equals(parameters('numberOfDataDisks'),0),1, parameters('numberOfDataDisks'))]",
      "input": {
        "lun": "[copyIndex('dataDisks')]",
        "createOption": "Empty",
        "diskSizeGB": "1023"
      }
  }   ]
  • In der VM - Ressource für Datenfestplatten.
  • Wenn auf der Ressource VM die Zahl numDisk = 0 ist, dann sind datadisks = json ("null") else datadisks = variable
"dataDisks": 
                "[if(equals(parameters('numberOfDataDisks'),0),json('null'),variables('dataDisks'))]"

            },
0