Tworzenie wielu wystąpień zasobów przy użyciu elementu copy

Ukończone

Do tej pory deklarowano zasoby na liście zasobów w szablonie. W przypadku wdrażania uzyskujesz jedno wystąpienie każdego elementu określonego na liście zasobów. Może być koniecznie utworzenie więcej niż jednego wystąpienia określonego zasobu. Może być to na przykład sytuacja, w której będziesz potrzebować wielu podsieci w sieci wirtualnej.

Weź pod uwagę następujące pytania i punkty podczas rozważania opcji utworzenia wielu wystąpień i iterowania konstrukcji:

  • Czy potrzebuję więcej niż jednej kopii: w przypadku prostszych scenariuszy możesz nie. W przypadku bardziej zaawansowanych scenariuszy, takich jak podsieci lub maszyny wirtualne, być może trzeba będzie się zastanowić, czy potrzebna jest więcej niż jedna kopia danego elementu.
  • Czy jestem zależny od zasobu: Zwykle usługa Azure Resource Manager jest dobra do ustalenia, co należy utworzyć w jakiej kolejności, aby odwołania w szablonie usługi Azure Resource Manager działały prawidłowo. Istnieją jednak sytuacje, w których może być konieczne określenie zamówienia.
  • Zdefiniuj schemat nazewnictwa: chcesz nadać zasobom znaczące nazwy. Z tego powodu opierasz się na parametrach przekazywanych w czasie wdrażania. Jeśli masz wiele kopii, możesz zdecydować się na bardziej szczegółową kontrolę i oprzeć nazewnictwo na iteracji w sekwencji kopiowania, w obrębie której aktualnie pracujesz.
  • Konfigurowanie i kontrolowanie tworzenia zasobów: możesz ograniczyć liczbę zasobów tworzonych w środowisku produkcyjnym. W tym celu możesz skonfigurować tworzenie zasobów jako seryjne lub równoległe.
  • Kopiowanie innych typów: Zasoby nie są jedyną rzeczą, którą można utworzyć wiele kopii i iterować. Te same czynności można również wykonywać w stosunku do właściwości, zmiennych i danych wyjściowych.
  • Element nadrzędny-podrzędny: może być konieczne skonfigurowanie relacji nadrzędny-podrzędny w zasobach.

Tworzenie wielu wystąpień

Można użyć konstrukcji pętli do zapisywania naciśnięć klawiszy. Jeśli potrzebne elementy są wielokrotnie powtarzane i mają stosunkowo podobne nazwy oraz typ, a różnice między nimi są niewielkie, korzystne może być użycie elementu copy.

Element copy to część kodu JSON, której można używać w wielu typach konstrukcji, takich jak zasoby, właściwości, zmienne i dane wyjściowe. Składnia elementu copy składa się z klucza copy i tablicy jako wartości. Na przykład: "copy": [].

Tablica przyjmuje wiele elementów, a każdy element jest obiektem {} składającym się z zestawu właściwości. Wybór właściwości do zestawu zależy od typu używanej konstrukcji. Przeważnie wszystkie konstrukcje elementów copy mają jedną wspólną właściwość: count. Ta właściwość decyduje o liczbie wystąpień określonego typu konstrukcji. W przypadku większości konstrukcji można również stosować właściwość name stanowiącą odwołanie, do którego można się odwoływać w innych częściach kodu. Inne używane właściwości są specyficzne dla konstrukcji.

Co należy wybrać

Możesz zapytać: "Jeśli mogę użyć copy elementu na wielu typach konstrukcji, które należy wybrać i kiedy, i czy mogę użyć więcej niż jednego typu w szablonie?"

Wszystko to zależy od przypadku użycia. Iteracja zasobów umożliwia tworzenie wielu kopii zasobu i warto ją zastosować, jeśli na przykład potrzebujesz wielu kont magazynu. Iteracja właściwości z drugiej strony umożliwia tworzenie wielu właściwości wewnątrz jednego zasobu. Pozwala to na zredukowanie liczby naciśnięć klawiszy i zaoszczędzenie czasu, a Ty najlepiej wiesz, które części w szablonie się powtarzają.

Elementu copy można użyć w wielu miejscach w szablonie. Element copy można stosować w celu utworzenia wielu zasobów, ale również do tworzenia wielu podobnych zmiennych w ramach tego samego szablonu.

Jak działa

Działanie elementu copy polega na oszacowaniu wartości instrukcji copy i jej zamianie. Zamiana jest wynikiem tego, co definiujesz w instrukcji copy powtarzanej tyle razy, ile instruujesz w copy polu.

Poniższy przykład pokazuje, jak może wyglądać definicja korzystająca z elementu copy:

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

Zanotuj wpis count: 2. Wartość 2 oznacza, że chcesz rozszerzyć powyższe wyrażenie do dwóch wpisów. Oto wynik:

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

Można zauważyć, że wartość właściwości name stała się nazwą właściwości, a zawartość właściwości input stała się częścią powtarzanego kodu JSON.

Uwaga

Wyrażenie kopiowania i jego dane wyjściowe różnią się w zależności od typu zastosowanego wyrażenia. Powyższy przykład dobrze pokazuje, co się dzieje, gdy wyrażenie jest przekształcane w serię powtarzających się instrukcji.

Istnieją limity dotyczące wielkości kopiowanych danych. Obecnie limit wynosi 800 wpisów.

Ważne

Aby uzyskać więcej informacji na temat dokładnych ograniczeń, zobacz Iteracja zasobów w szablonach usługi ARM.

Kontrolowanie iteracji

Istnieją funkcje pomocnika, które ułatwiają odwoływanie się do określonych indeksów w tablicy. Funkcja copyIndex() zwraca bieżący indeks. Na przykład dla trzeciego powtórzonego wpisu funkcja copyIndex() zwraca wartość 2. Składnia funkcji copyIndex() wygląda następująco:

copyIndex(loopName, offset)

Funkcja copyIndex() ma dwa różne parametry wejściowe: loopName i offset. Parametr offset jest zawsze opcjonalny i służy do wykonania przesunięcia z bieżącego indeksu. Wszystkie dane dodane jako wartość offset zostaną dodane do bieżącego indeksu. Jeśli bieżący indeks zwraca wartość 2, a Ty określisz element 1 jako przesunięcie, funkcja copyIndex() zwraca wartość 3.

Parametr loopName jest opcjonalny lub obowiązkowy, w zależności od tego, gdzie jest używany. Jest on wymagany, jeśli jest używany wewnątrz konstrukcji properties, i opcjonalny, jeśli jest używany w tablicy resources. Oto przykład sytuacji, w której parametr jest obowiązkowy:

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

Zwróć uwagę na to, że element copy jest używany wewnątrz konstrukcji properties, a funkcja copyIndex() ma parametr loopName określony jako copyIndex('dataDisks').

Oto przykład sytuacji, w której parametr loopName nie jest obowiązkowy:

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

Pokazuje zadeklarowany zasób, a funkcja copyIndex() jest wywoływana bez parametrów, ponieważ jest używana w kontekście zasobu.

Konfigurowanie wdrożenia

W przypadku używania elementu copy dla zasobów można utworzyć wiele podobnie wyglądających zasobów.

Czasami warto kontrolować sposób i kolejność tworzenia zasobów. Przyczyny kontrolowania kolejności mogą być następujące:

  • Ograniczenia środowiska. W zależności od wdrażanego środowiska możesz ograniczyć obszar tego środowiska, na który wdrożenie będzie mieć wpływ. W środowisku produkcyjnym warto ograniczyć zasobów, których w dowolnym momencie to dotyczy. Można skonfigurować tryb wdrożenia, aby kontrolować liczbę wdrażanych jednocześnie zasobów.
  • Zależności. Możliwość utworzenia potrzebnego zasobu może zależeć od wcześniejszego istnienia pewnego elementu. Do wyrażania takiej zależności służy konstrukcja o nazwie dependsOn.

Tryby wdrażania i copy

Warto upewnić się, że wszystkie zasoby utworzone przez konstrukcję copy są tworzone przed wszystkimi innymi elementami. W takim przypadku należy wyrazić odpowiednio tę sytuację. Pamiętaj, że w tym miejscu używany jest tryb wdrażania stosowany przez usługę Resource Manager. Obsługiwane są dwa tryby:

  • Szeregowe. Ustawienie zasobu na ten tryb wdrożenia oznacza, że zasoby będą tworzone jeden po drugim. W tym trybie oczekuje się również, że właściwość batchSize zostanie ustawiona w celu określenia, ile zasobów będzie wdrażanych przy użyciu tego trybu. Nie można uruchomić nowej partii przed ukończeniem poprzedniej partii. Tej funkcji ograniczania warto używać w środowisku produkcyjnym, na przykład gdy może być ważne ograniczenie liczby uwzględnionych zasobów w danym momencie.
  • Równoległe. Jest to domyślny tryb wdrażania. Jego zaletą jest wysoka przepływność, dzięki której przetwarzanie szablonu kończy się szybciej. Wadą jest to, że nie można zagwarantować kolejności oraz że może być to sytuacja niepożądana w środowisku produkcyjnym.

Zależności

W kontekście elementu copy musisz poinformować zasób za pomocą zależności, na którą sekcję oczekuje. Tę zależność można zrealizować, odwołując się do niej według nazwy, korzystając z poniższego kodu JSON:

"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"],
    }
  ]

Należy zauważyć, że element copy ma właściwość name, której wartością jest storagecopy. Zasób zależny, konto magazynu oczekuje na zakończenie operacji elementu copy. Jest to wyrażone jako "dependsOn": ["storagecopy"].

W rezultacie szablon usługi ARM przechodzi do trybu wdrażania szeregowego między tymi dwoma zasobami. Może to mieć wpływ na szybkość przepływności wdrożenia, ale pokazano, że ważna jest określona kolejność wdrażania, która teraz ma pierwszeństwo.