Erstellen mehrerer Ressourceninstanzen mit dem copy-Element

Abgeschlossen

Bisher haben Sie Ressourcen in einer Ressourcenliste in einer Vorlage deklariert. Bei der Bereitstellung erhalten Sie eine Instanz jedes in der Ressourcenliste angegebenen Elements. Möglicherweise ist es sinnvoll, mehrere Instanzen einer bestimmten Ressource erstellen. Beispielsweise kann es sein, dass Sie mehrere Subnetze in einem virtuellen Netzwerk benötigen.

Berücksichtigen Sie die folgenden Fragen und Aspekte, wenn Sie überlegen, mehrere Instanzen zu erstellen und Konstrukte zu durchlaufen:

  • Benötige ich mehrere Instanzen: Bei einfacheren Szenarios lautet die Antwort möglicherweise „nein“. Bei erweiterten Szenarios, z. B. bei Subnetzen oder virtuellen Computern, müssen Sie möglicherweise in Erwägung ziehen, dass Sie mehrere Instanzen von Ressourcen benötigen.
  • Bin ich von einer Ressource abhängig: In der Regel kann Azure Resource Manager gut herausfinden, was in welcher Reihenfolge erstellt werden muss, damit Verweise in der ARM-Vorlage (Azure Resource Manager) funktionieren. Es gibt jedoch Situationen, in denen Sie möglicherweise die Reihenfolge selbst angeben müssen.
  • Definieren eines Benennungsschemas: Sie möchten Ihre Ressourcen mit aussagekräftigen Namen versehen. Aus diesem Grund verlassen Sie sich auf Parameter, die zum Zeitpunkt der Bereitstellung übergeben werden. Wenn Sie mehrere Kopien haben, möchten Sie vielleicht eine genauere Kontrolle haben und die Benennung davon abhängig machen, in welcher Iteration der Kopiersequenz Sie sich zurzeit befinden.
  • Konfigurieren und Steuern der Ressourcenerstellung: Möglicherweise möchten Sie einschränken, wie viele Ressourcen in einer Produktionsumgebung erstellt werden. Dies ist möglich, indem Sie die Ressourcenerstellung als seriell oder parallel konfigurieren.
  • Kopieren anderer Typen: Ressourcen sind nicht die einzigen Objekte, von denen Sie mehrere Kopien erstellen und die Sie durchlaufen können. Dies gilt auch für Eigenschaften, Variablen und Ausgaben.
  • Übergeordnet/untergeordnet: Möglicherweise müssen Sie Beziehungen zwischen übergeordneten/untergeordneten Elementen in ihren Ressourcen konfigurieren.

Erstellen mehrerer Instanzen

Mit Schleifenkonstrukten können Sie Tastatureingaben sparen. Wenn das, was Sie brauchen, sich immer wieder wiederholt, ziemlich ähnlich in Name und Typ und es nur geringfügige Unterschiede gibt, können Sie von der Verwendung des copy-Elements profitieren.

Das copy-Element ist ein JSON-Element, das Sie für viele Konstrukttypen wie Ressourcen, Eigenschaften, Variablen und Ausgaben verwenden können. Die Syntax für das copy-Element besteht aus dem Schlüssel copy und wird mit einem Array als Wert verwendet. Beispiel: "copy": [].

Das Array nimmt eine Reihe von Elementen an, und jedes Element ist ein Objekt-{} mit Eigenschaften. Welche Eigenschaften dies sind, hängt davon ab, für welche Art von Konstrukt sie verwendet werden. In der Regel verfügen alle copy-Elementkonstrukte über eine gemeinsame Eigenschaft count. Diese Eigenschaft bestimmt, wie viele Instanzen Sie für einen bestimmten Typ von Konstrukt wünschen. Die meisten Konstrukte ermöglichen auch eine name-Eigenschaft, die einen Verweis enthält, auf den Sie in anderen Teilen Ihres Codes verweisen können. Andere verwendete Eigenschaften sind konstruktspezifisch.

Auswahlmöglichkeiten

Möglicherweise fragen Sie sich: „Wenn das copy-Element für viele Konstrukttypen verwendet werden kann, sollte welcher Typ wann ausgewählt werden, und können mehrere Typen in einer Vorlage verwendet werden?“

Dies alles hängt von Ihrem Anwendungsfall ab. Mit einer Ressourceniteration können Sie viele Kopien einer Ressource erstellen. Dies ist sinnvoll, wenn Sie z. B. viele Speicherkonten benötigen. Eine Eigenschafteniteration ermöglicht es Ihnen anderseits, viele Eigenschaften innerhalb einer Ressource zu erstellen. Dabei geht es darum, Tastatureingaben und Zeit zu sparen. Außerdem wissen Sie am besten, wo in ihrer Vorlage Wiederholungen vorhanden sind.

Sie können das copy-Element an vielen Stellen in Ihrer Vorlage verwenden. Sie können ein copy-Element verwenden, um viele Ressourcen zu erstellen, aber auch, um viele ähnliche Variablen in derselben Vorlage zu erstellen.

Funktionsweise

Das copy-Element funktioniert durch Auswerten und Ersetzen Ihrer copy-Anweisung. Diese Ersetzung ist das Ergebnis der Definition, die Sie innerhalb der copy-Anweisung so oft wiederholen, wie Sie im Feld copy angewiesen haben.

Im folgenden Beispiel ist eine Definition mit copy dargestellt:

"copy": [
  {
    "name": "dataDisks",
    "count": 2,
    "input": {
      "diskSizeGB": 1023,
      "lun": "[copyIndex('dataDisks')]",
      "createOption": "Empty"
    }
  }
]

Beachten Sie den Eintrag count: 2. Der Wert 2 bedeutet, dass der oben verwendete Ausdruck auf zwei Einträge erweitert werden soll. Und so sieht das Ergebnis aus:

"dataDisks": [
{
  "lun": 0,
  "createOption": "Empty",
  "diskSizeGB": 1023
},
{
  "lun": 1,
  "createOption": "Empty",
  "diskSizeGB": 1023
}

Wie Sie sehen, ist der Wert der name-Eigenschaft zum Eigenschaftsnamen geworden und der Inhalt der input-Eigenschaft wird zu dem Teil des JSON-Codes, der wiederholt wird.

Hinweis

Der copy-Ausdruck und seine Ausgabe unterscheiden sich abhängig vom Ausdruckstyp, der verwendet wird. Das obige Beispiel vermittelt eine gute Vorstellung davon, was passiert, wenn ein Ausdruck in eine Reihe von wiederholten Anweisungen transformiert wird.

Es gibt Einschränkungen, wie viel kopiert werden kann. Der Grenzwert liegt derzeit bei 800 Einträgen.

Wichtig

Weitere Informationen zu den genauen Einschränkungen finden Sie unter Ressourceniteration in ARM-Vorlagen.

Steuern der Iteration

Es gibt Hilfsfunktionen, mit denen Sie auf bestimmte Indizes im Array verweisen können. Die copyIndex()-Funktion gibt den aktuellen Index zurück. Beim dritten Eintrag gibt copyIndex() beispielsweise den Wert 2 zurück. Die Syntax von copyIndex() sieht wie folgt aus:

copyIndex(loopName, offset)

Die copyIndex()-Funktion verfügt über zwei verschiedene Eingabeparameter loopName und offset. Der Parameter offset ist immer optional und wird als Offset vom aktuellen Index verwendet. Was Sie als offset-Wert hinzufügen, wird dem aktuellen Index hinzugefügt. Wenn der aktuelle Index 2 zurückgibt und Sie 1 als Offset angeben, gibt die copyIndex()-Funktion 3 zurück.

Der loopName-Parameter ist je nachdem, wo er verwendet wird, entweder optional oder obligatorisch. Der Parameter ist obligatorisch, wenn er in einem properties-Konstrukt verwendet wird, und optional, wenn er in einem resources-Array verwendet wird. Das folgende Beispiel zeigt den obligatorischen Fall:

"properties": {
    "storageProfile": {
      "copy": [
        {
          "name": "dataDisks",
          "count": "[parameters('numberOfDataDisks')]",
          "input": {
            "diskSizeGB": 1023,
            "lun": "[copyIndex('dataDisks')]",
            "createOption": "Empty"
          }
        }
      ]
    }
}

Beachten Sie, wie das copy-Element innerhalb eines properties-Konstrukts verwendet wird und dass für copyIndex()loopName als copyIndex('dataDisks') angegeben wird.

Das folgende Beispiel zeigt nun den Fall, in dem loopName nicht obligatorisch ist:

{
  "type": "Microsoft.Network/virtualNetworks",
  "apiVersion": "2018-04-01",
  "name": "[concat(parameters('vnetname'), copyIndex())]",
}

Hier ist zu sehen, wie eine Ressource deklariert wird und copyIndex() ohne Parameter aufgerufen wird, da die Verwendung im Kontext einer Ressource erfolgt.

Konfigurieren der Bereitstellung

Wenn Sie das copy-Element für Ressourcen verwenden, erstellen Sie letztlich viele ähnlich aussehende Ressourcen.

Manchmal möchten Sie vielleicht steuern, wie Ressourcen erstellt werden und in welcher Reihenfolge. Für das Steuern der Reihenfolge können folgenden Gründe vorliegen:

  • Umgebungseinschränkungen. Abhängig von der Umgebung, in der die Bereitstellung erfolgt, möchten Sie ggf. einschränken, in welchem Umfang diese Umgebung von einer Bereitstellung betroffen ist. In einer Produktionsumgebung ist es sinnvoll, die Anzahl der Ressourcen einzuschränken, die jeweils betroffen sind. Sie können einen Bereitstellungsmodus so konfigurieren, dass die Anzahl gleichzeitig bereitgestellter Ressourcen gesteuert wird.
  • Abhängigkeiten Möglicherweise muss eine bestimmte Ressource bereits vorhanden sein, damit Sie eine andere benötigte Ressource erstellen können. Zum Ausdrücken einer solchen Abhängigkeit gibt es ein Konstrukt namens dependsOn.

Bereitstellungsmodi und copy

Möglicherweise möchten Sie sicherstellen, dass eine Gruppe von Ressourcen, die vom copy-Konstrukt erstellt werden, vor einer anderen Ressource erstellt werden. Wenn dies der Fall ist, müssen Sie diese Situation ausdrücken. Denken Sie daran, dass es hier um die Bereitstellungsmodi geht, die Resource Manager verwendet. Zwei Modi werden unterstützt:

  • Seriell. Das Festlegen einer Ressource auf diesen Bereitstellungsmodus bedeutet, dass Ressourcen nacheinander erstellt werden. In diesem Modus wird auch erwartet, dass Sie die Eigenschaft batchSize festlegen, um zu bestimmen, wie viele Ressourcen mit diesem Modus bereitgestellt werden. Ein neuer Batch kann nicht gestartet werden, bevor ein vorheriger Batch abgeschlossen wurde. Möglicherweise ist es sinnvoll, Dinge in einer Produktionsumgebung auf diese Weise einzuschränken, in der es ggf. wichtig ist, die Anzahl der betroffenen Ressourcen an einem bestimmten Punkt einzuschränken.
  • Parallel. Dieser Modus ist der Standardbereitstellungsmodus. Der Vorteil ist ein hoher Durchsatz, sodass die Vorlage schneller verarbeitet wird. Die Nachteile liegen darin, dass Sie die Reihenfolge nicht garantieren können. Und dies ist möglicherweise nicht das, was Sie für eine Produktionsumgebung wünschen.

Abhängigkeiten

Im Kontext des copy-Elements müssen Sie der Ressource mit der Abhängigkeit mitteilen, auf welchen Abschnitt sie wartet. Sie erreichen diese Abhängigkeit, indem Sie auf sie anhand des Namens mit dem folgenden JSON-Code verweisen:

"resources": [
    {
      "type": "Microsoft.Storage/storageAccounts",
      "apiVersion": "2019-04-01",
      "name": "[concat(copyIndex(),'storage', uniqueString(resourceGroup().id))]",
      "location": "[resourceGroup().location]",
      "sku": {
        "name": "Standard_LRS"
      },
      "kind": "Storage",
      "copy": {
        "name": "storagecopy",
        "count": 3
      },
      "properties": {}
    },
    {
      "type": "Microsoft.Compute/virtualMachines",
      "apiVersion": "2015-06-15",
      "name": "[concat('VM', uniqueString(resourceGroup().id))]",
      "dependsOn": ["storagecopy"],
    }
  ]

Beachten Sie, dass das copy-Element über eine name-Eigenschaft mit dem Wert storagecopy verfügt. Die abhängige Ressource (ein Speicherkonto) wartet darauf, dass der Vorgang des copy-Elements abgeschlossen wird. Dies wird durch "dependsOn": ["storagecopy"] ausgedrückt.

Die ARM-Vorlage wechselt dadurch zwischen diesen beiden Ressourcen in einen seriellen Bereitstellungsmodus. Dies kann sich auf die Durchsatzgeschwindigkeit der Bereitstellung auswirken, aber Sie haben angegeben, dass Sie eine bestimmte Bereitstellungsreihenfolge wünschen, die nun Vorrang besitzt.