Créer plusieurs instances de ressource à l’aide de l’élément copy

Effectué

Vous avez jusqu’à présent des ressources déclarées dans une liste de ressources dans un modèle. Lors du déploiement, vous obtenez une instance de chaque élément spécifié dans la liste de ressources. Vous pouvez être amené à créer plusieurs instances d’une ressource spécifique. Par exemple, vous pouvez souhaiter disposer de plusieurs sous-réseaux dans un réseau virtuel.

Tenez compte des questions et des points suivants quand vous songez à créer de nombreuses instances et à effectuer une itération sur les constructions :

  • Ai-je besoin de plusieurs copies : Pour des scénarios plus simples, ce n’est peut-être pas le cas. Pour des scénarios plus avancés, par exemple ceux qui impliquent des sous-réseaux ou des machines virtuelles, vous devrez peut-être déterminer si vous avez besoin de plusieurs copies de quelque chose.
  • Est-ce que je dépends d’une ressource : En règle générale, Azure Resource Manager sait déterminer ce qui doit être construit et dans quel ordre pour permettre le bon fonctionnement des références au sein du modèle Azure Resource Manager. Toutefois, dans certains cas, vous pouvez être amené à spécifier l’ordre.
  • Définir un schéma de nommage : Vous souhaitez attribuer à vos ressources des noms explicites. C’est la raison pour laquelle vous utilisez des paramètres qui sont passés au moment du déploiement. Quand vous avez plusieurs copies, vous souhaitez peut-être avoir un contrôle plus précis et baser le nommage sur l’itération de la séquence de copie active.
  • Configurer et contrôler la création de ressources : Vous souhaiterez peut-être limiter le nombre de ressources créées dans un environnement de production. Pour ce faire, vous pouvez configurer la création de ressources pour qu’elle s’effectue en série ou en parallèle.
  • Copier les autres types : Les ressources ne sont pas les seuls éléments à pouvoir créer plusieurs copies et faire l’objet une itération. En fait, vous pouvez en faire de même avec les propriétés, les variables et la sortie.
  • Parent-enfant : Vous devrez peut-être configurer les relations parent-enfant dans vos ressources.

Créer plusieurs instances

Vous pouvez utiliser des boucles de constructions pour vous éviter des frappes inutiles au clavier. Si ce dont vous avez besoin se répète fréquemment, est relativement similaire au niveau du nom et du type, et présente simplement de légères différences, vous pouvez tirer parti de l’élément copy.

L’élément copy est un élément JSON que vous pouvez utiliser sur de nombreux types de construction, par exemple les ressources, les propriétés, les variables et la sortie. La syntaxe de l’élément copy se compose de la clé copy et d’un tableau en tant que valeur. Par exemple : "copy": [].

Le tableau accepte un certain nombre d’éléments. Chacun d’eux est un objet {} constitué d’un ensemble de propriétés. La nature de ces propriétés dépend du type de construction sur lequel elles sont utilisées. En règle générale, toutes les constructions d’élément copy ont une propriété en commun : count. Cette propriété détermine le nombre d’instances que vous souhaitez pour un certain type de construction. La plupart des constructions autorisent également une propriété name qui vous donne une référence que vous pouvez référencer dans d’autres parties de votre code. Les autres propriétés utilisées sont spécifiques à la construction.

Que choisir

Vous pouvez vous poser les questions suivantes : « Si je peux utiliser l’élément copy sur de nombreux types de construction, lequel dois-je choisir et à quel moment ? De plus, puis-je utiliser plusieurs types dans un modèle ? »

Tout dépend de votre cas d’usage. Une itération de ressource vous permet de créer de nombreuses copies d’une ressource et d’utiliser plusieurs comptes de stockage si vous en avez besoin, par exemple. Une itération de propriété vous permet quant à elle de créer de nombreuses propriétés à l’intérieur d’une seule ressource. Cela vous permet de gagner du temps en évitant les frappes inutiles, et de mieux identifier les emplacements qui contiennent des parties répétitives dans votre modèle.

Vous pouvez utiliser l’élément copy à de nombreux emplacements dans votre modèle. Vous pouvez utiliser un élément copy pour créer de nombreuses ressources, mais également pour créer de nombreuses variables similaires dans le même modèle.

Fonctionnement

L’élément copy fonctionne parallèlement à l’évaluation et au remplacement de l’instruction copy. Le remplacement est le résultat de ce que vous définissez dans l’instruction copy répétée autant de fois que vous l’avez indiqué dans le champ copy.

L’exemple suivant montre comment se présente une définition utilisant copy :

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

Notez l’entrée count: 2. La valeur 2 signifie que vous souhaitez que l’expression ci-dessus s’étende à deux entrées. Voici le résultat :

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

Vous pouvez voir que la valeur de la propriété name est devenue le nom de la propriété, et que le contenu de la propriété input est devenu la partie du code JSON répété.

Notes

L’expression de copie et sa sortie diffèrent par le type d’expression utilisé. L’exemple précédent donne une bonne idée de ce qui se passe quand une expression est transformée en une série d’instructions répétées.

Il existe des limites quant à la quantité pouvant être copiée. La limite actuelle est de 800 entrées.

Important

Pour plus d’informations sur les limitations exactes, consultez Itération de ressource dans les modèles ARM.

Contrôler l’itération

Il existe des fonctions d’assistance qui vous aident à faire référence à des index spécifiques dans le tableau. La fonction copyIndex() retourne l’index actuel. Par exemple, pour la troisième entrée répétée, copyIndex() retourne la valeur 2. La syntaxe de copyIndex() ressemble à ce qui suit :

copyIndex(loopName, offset)

La fonction copyIndex() a deux paramètres d’entrée différents, loopName et offset. Le paramètre offset est toujours facultatif et est utilisé pour vous décaler de l’index actuel. Tout ce que vous ajoutez en tant que valeur offset est ajouté à l’index actuel. Si l’index actuel retourne 2 et si vous spécifiez 1 en tant que décalage, la fonction copyIndex() retourne 3.

Le paramètre loopName est facultatif ou obligatoire, en fonction de son utilisation. Il est obligatoire s’il est utilisé dans une construction properties, et facultatif s’il est utilisé dans un tableau resources. Voici un exemple où il est obligatoire :

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

Notez la façon dont l’élément copy est utilisé dans une construction properties, et notez que copyIndex() a le loopName spécifié en tant que copyIndex('dataDisks').

Voici à présent un exemple où loopName n’est pas obligatoire :

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

Il montre la déclaration d’une ressource et l’appel de copyIndex() sans aucun paramètre, car il est utilisé dans le contexte d’une ressource.

Configurer le déploiement

Quand vous utilisez l’élément copy pour des ressources, vous finissez par créer de nombreuses ressources similaires.

Il peut arriver que vous souhaitiez contrôler la façon dont les ressources sont créées et dans quel ordre. Il existe plusieurs raisons qui poussent à vouloir contrôler cet ordre de création :

  • Limitations de l’environnement. Selon l’environnement sur lequel vous effectuez le déploiement, vous pouvez être amené à limiter l’impact de ce dernier. Dans un environnement de production, il est logique de limiter le nombre de ressources affectées à un moment donné. Vous pouvez configurer un mode de déploiement pour contrôler le nombre de ressources déployées simultanément.
  • Dépendances. Vous pouvez dépendre de l’existence préalable de quelque chose avant de commencer à créer la ressource dont vous avez besoin. Pour exprimer une telle dépendance, il existe une construction appelée dependsOn.

Modes de déploiement et copy

Vous pouvez être amené à vérifier qu’un ensemble de ressources créées par la construction copy est entièrement créé avant autre chose. Si c’est le cas, vous devez exprimer cette situation. Rappelez-vous ce qui entre en jeu ici, à savoir le mode de déploiement utilisé par Resource Manager. Deux modes sont pris en charge :

  • Série. Le fait de définir des ressources sur ce mode de déploiement signifie qu’elles seront créées l’une après l’autre. Dans ce mode, vous devez également définir la propriété batchSize pour déterminer le nombre de ressources déployées à l’aide de ce mode. Il est impossible de démarrer un nouveau lot avant la fin du précédent. Cela peut vous être utile dans un environnement de production, par exemple, où il est important de limiter le nombre de ressources affectées à un moment quelconque.
  • Parallèle. Il s’agit du mode de déploiement par défaut. L’avantage est un débit élevé, ce qui se traduit par un traitement plus rapide du modèle. L’inconvénient est que vous ne pouvez pas garantir l’ordre, ce qui n’est peut-être pas ce que vous souhaitez pour un environnement de production.

Les dépendances

Dans le contexte de l’élément copy, vous devez indiquer à la ressource ayant la dépendance quelle est la section qu’elle attend. Pour mettre en œuvre cette dépendance, vous devez faire référence à celle-ci par son nom à l’aide du code JSON suivant :

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

Notez que l’élément copy a une propriété name ayant la valeur storagecopy. La ressource dépendante, un compte de stockage, attend la fin de l’opération relative à l’élément copy. Cela est exprimé par "dependsOn": ["storagecopy"].

Le modèle ARM passe ainsi à un mode de déploiement en série entre ces deux ressources. Cela peut affecter le débit du déploiement, mais vous avez indiqué que vous préférez un certain ordre de déploiement, lequel est désormais prioritaire.