Skapa flera resursinstanser med elementet copy

Slutförd

Hittills har du deklarerat resurser i en resurslista i en mall. När du distribuerar får du en instans av varje objekt som anges i resurslistan. Du kanske dock vill skapa fler än en instans av en viss resurs. Du kanske till exempel vill ha flera undernät i ett virtuellt nätverk.

Tänk på följande frågor när du tänker på att skapa många instanser och iterera över konstruktioner:

  • Behöver jag mer än en kopia: För enklare scenarier kanske du inte gör det. I mer avancerade scenarier som för undernät och virtuella datorer kan du behöva fundera på om du behöver fler än en kopia av någonting.
  • Är jag beroende av en resurs: Normalt är Azure Resource Manager bra på att ta reda på vad som behöver konstrueras i vilken ordning, så att referenser i Azure Resource Manager-mallen fungerar. Det finns dock situationer där du kan behöva ange ordningen.
  • Definiera ett namngivningsschema: Du vill ge dina resurser meningsfulla namn. Därför använder du parametrar som skickas vid distributionstillfället. När du har flera kopior kanske du vill ha större kontroll och basera namngivningen på vilken iteration i kopieringsordningen det gäller.
  • Konfigurera och kontrollera resursskapande: Du kanske vill begränsa hur många resurser som skapas i en produktionsmiljö. Det kan du göra genom att konfigurera resursskapandet som seriellt eller parallellt.
  • Kopiera andra typer: Resurser är inte det enda du kan skapa flera kopior av och iterera över. Du kan faktiskt göra samma sak med egenskaper, variabler och utdata.
  • Överordnad-underordnad: Du kan behöva konfigurera överordnade och underordnade relationer i dina resurser.

Skapa flera instanser

Du kan använda loopar för att spara tangenttryckningar. Om det du behöver upprepas om och om igen, har ett liknande namn och typ och bara små skillnader kan du använda copy-elementet.

copy-elementet är JSON-kod som kan användas i många typer av konstruktioner som resurser, egenskaper, variabler och utdata. Syntaxen för copy-elementet består av nyckeln copy och en matris som värde. Exempel: "copy": [].

Matrisen innehåller ett antal element och varje element är ett objekt {} som består av en uppsättning egenskaper. Vilka egenskaperna är beror på vilken typ av konstruktion de används på. Vanligtvis har alla copy-elementkonstruktioner en gemensam egenskap: count. Den här egenskapen avgör hur många instanser du vill ha av en viss konstruktion. De flesta konstruktioner kan också ha egenskapen name så att du kan referera till konstruktionen i andra delar av koden. Övriga egenskaper är konstruktionsspecifika.

Så här väljer du

Du kanske frågar: "Om jag kan använda elementet copy på många typer av konstruktioner, vilken ska jag välja och när, och kan jag använda mer än en typ i en mall?"

Allt beror på ditt användningsfall. Med en resursiteration kan du skapa många kopior av en resurs vilket är bra om du till exempel behöver många lagringskonton. Med egenskapsiteration kan du å andra sidan skapa många egenskaper i en resurs. Det handlar om att spara tangenttryckningar, och du vet bäst själv var det förekommer upprepade delar i mallen.

Du kan använda copy-elementet på många platser i mallen. Du kan använda ett copy-element till att skapa flera resurser, men även till att skapa många liknande variabler i samma mall.

Så här fungerar det

Elementet copy fungerar så att din copy-instruktion utvärderas och ersätts. Ersättningen är resultatet av det du definierar i -instruktionen copy som upprepas så många gånger som du instruerade i fältet copy .

I följande exempel visas hur en definition som använder copy kan se ut:

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

Observera posten count: 2. Värdet 2 innebär att du vill utöka uttrycket ovan till två poster. Följande är resultatet:

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

Du kan se att värdet för egenskapen name har blivit egenskapsnamnet och att innehållet i egenskapen input har blivit den del av JSON-koden som upprepas.

Kommentar

copy-uttrycket och dess utdata varierar beroende på vilken typ av uttryck som används. Föregående exempel ger dig en bra uppfattning om vad som händer när ett uttryck omvandlas till en serie upprepade instruktioner.

Det finns gränser för hur mycket som kan kopieras. För närvarande är gränsen 800 poster.

Viktigt!

Mer information om de exakta begränsningarna finns i Resource iteration in ARM templates (Resursiteration i ARM-mallar).

Styra iterationen

Det finns hjälpfunktioner som hjälper dig att referera till specifika index i matrisen. Funktionen copyIndex() returnerar aktuellt index. För den tredje upprepade posten returnerar copyIndex() till exempel värdet 2. Syntaxen för copyIndex() ser ut så här:

copyIndex(loopName, offset)

Funktionen copyIndex() har två olika indataparametrar, loopName och offset. Parametern offset är alltid valfri och används till att förskjuta dig från det aktuella indexet. Det som du lägger till som offset-värde läggs till i det aktuella indexet. Om det aktuella indexet returnerar 2 och du anger 1 som förskjutning så skulle funktionen copyIndex() returnera 3.

Parametern loopName är antingen valfri eller obligatorisk beroende på var den används. Den är obligatorisk om den används inuti en properties-konstruktion och valfri om den används i en resources-matris. Nedan visas ett exempel där den är obligatorisk:

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

Observera hur copy-element används i en properties-konstruktion, och copyIndex() har loopName angetts som copyIndex('dataDisks').

Nedan visas ett exempel där loopName inte är obligatoriskt:

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

Det visar en resurs som deklareras och där copyIndex() anropas utan parametrar, eftersom funktionen används i en resurskontext.

Konfigurera distributionen

När du använder elementet copy för resurser skapar du flera liknande resurser.

Ibland kanske du vill styra hur resurserna skapas och i vilken ordning. Anledningarna till att styra ordningen kan vara:

  • Miljöbegränsningar. Beroende på vilken miljö du distribuerar till kanske du vill begränsa hur mycket miljön påverkas av distributionen. I en produktionsmiljö är det klokt att begränsa hur många resurser som påverkas vid ett och samma tillfälle. Du kan konfigurera ett distributionsläge för att styra hur många resurser som distribuerats samtidigt.
  • Beroenden. Du kan vara beroende av att något redan finns innan du skapar den resurs du behöver. För att uttrycka ett sådant beroende finns en konstruktion som heter dependsOn.

Distributionslägen och copy

Du kanske vill se till att en uppsättning resurser som skapas med konstruktionen copy skapas innan någonting annat. I så fall måste du uttrycka det. Kom ihåg att det som används här är samma distributionslägen som i Resource Manager. Två lägen stöds:

  • Seriellt läge. Om du anger det här distributionsläget för en resurs skapas de en efter en. I det här läget förväntas du också ange egenskapen batchSize som avgör hur många resurser som ska distribueras i det här läget. Det går inte att starta en ny batch innan en tidigare batch har slutförts. Du kanske vill begränsa saker på det här sättet, till exempel i en produktionsmiljö där det kan vara viktigt att begränsa hur många resurser som påverkas samtidigt.
  • Parallellt läge. Det här distributionsläget är standardalternativet. Fördelen är ett större dataflöde så att mallen kan bearbetas snabbare. Nackdelen är att du inte kan garantera ordningen, och det kanske du vill göra om det gäller en produktionsmiljö.

Beroenden

I samband med copy-elementet måste du meddela resursen med beroendet vilken sektion den väntar på. Det gör du genom att referera till den med namn, som i följande JSON-kod:

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

Observera att copy-elementet har en name-egenskap med värdet storagecopy. Den beroende resursen, ett lagringskonto, väntar på att copy-elementåtgärden ska slutföras. Detta uttrycks av "dependsOn": ["storagecopy"].

På så sätt växlar ARM-mallen till ett seriellt distributionsläge mellan de två resurserna. Det kan påverka distributionens dataflödeshastighet, men du har uttryckt att du bryr dig om en viss distributionsordning som nu kommer att ha företräde.