Définir l’ordre de déploiement des ressources dans les modèles ARM

Quand vous déployez des ressources, vous devez éventuellement vous assurer que certaines ressources existent au préalable avant d’autres ressources. Par exemple, vous avez besoin d’un serveur SQL logique avant de déployer une base de données. Vous établissez cette relation en marquant une seule ressource comme dépendante de l’autre ressource. Utilisez l’élément dependsOn pour définir une dépendance explicite. Utilisez les fonctions reference ou list pour définir une dépendance implicite.

Azure Resource Manager évalue les dépendances entre les ressources et les déploie dans leur ordre dépendant. Quand les ressources ne dépendent pas les unes des autres, Resource Manager les déploie en parallèle. Vous devez uniquement définir des dépendances pour les ressources qui sont déployées dans le même modèle.

Conseil

Nous recommandons Bicep, parce qu’il offre les mêmes fonctionnalités que les modèles ARM et que la syntaxe est plus facile d’utilisation. Pour plus d’informations, consultez les dépendances de ressource.

dependsOn

Dans votre modèle Azure Resource Manager (modèle ARM), l’élément dependsOn vous permet de définir une ressource comme dépendante d’une ou de plusieurs ressources. Sa valeur est un tableau JavaScript Object Notation (JSON) de chaînes, chacune d’elles représentant un nom ou un ID de ressource. Le tableau peut inclure des ressources déployées de manière conditionnelle. Quand une ressource conditionnelle n’est pas déployée, Azure Resource Manager la supprime automatiquement des dépendances nécessaires.

L’exemple suivant montre une interface réseau qui dépend d’un réseau virtuel, d’un groupe de sécurité réseau et d’une adresse IP publique. Pour obtenir le modèle complet, consultez le modèle de démarrage rapide pour une machine virtuelle Linux.

{
  "type": "Microsoft.Network/networkInterfaces",
  "apiVersion": "2022-07-01",
  "name": "[variables('networkInterfaceName')]",
  "location": "[parameters('location')]",
  "dependsOn": [
    "[resourceId('Microsoft.Network/networkSecurityGroups/', parameters('networkSecurityGroupName'))]",
    "[resourceId('Microsoft.Network/virtualNetworks/', parameters('virtualNetworkName'))]",
    "[resourceId('Microsoft.Network/publicIpAddresses/', variables('publicIpAddressName'))]"
  ],
  ...
}

Avec languageVersion 2.0, utilisez le nom symbolique de ressource dans les tableaux dependsOn. Par exemple :

{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "languageVersion": "2.0",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "location": {
      "type": "string",
      "defaultValue": "[resourceGroup().location]"
    }
  },
  "resources": {
    "myStorage": {
      "type": "Microsoft.Storage/storageAccounts",
      "apiVersion": "2023-01-01",
      "name": "[format('storage{0}', uniqueString(resourceGroup().id))]",
      "location": "[parameters('location')]",
      "sku": {
        "name": "Standard_LRS"
      },
      "kind": "StorageV2"
    },
    "myVm": {
      "type": "Microsoft.Compute/virtualMachines",
      "apiVersion": "2023-03-01",
      "name": "[format('vm{0}', uniqueString(resourceGroup().id))]",
      "location": "[parameters('location')]",
      "dependsOn": [
        "myStorage"
      ],
      ...
    }
  }
}

Vous pouvez être tenté d’utiliser dependsOn pour mapper les relations entre vos ressources. Il est toutefois important de comprendre pourquoi vous le faites. Par exemple, pour documenter la manière dont les ressources sont liées entre elles, dependsOn n’est pas la bonne approche. Après le déploiement, la ressource ne conserve pas les dépendances de déploiement dans ses propriétés. Aucune commande ni opération ne vous permet donc d’afficher les dépendances. La définition de dépendances inutiles ralentit le temps de déploiement, Resource Manager ne pouvant pas déployer ces ressources en parallèle.

Ressources enfants

Aucune dépendance de déploiement implicite n’est créée automatiquement entre une ressource enfant et la ressource parent. Si vous devez déployer la ressource enfant après la ressource parent, définissez la propriété dependsOn.

L’exemple suivant montre un serveur SQL et une base de données. Notez qu’une dépendance explicite est définie entre la base de données et le serveur, même si la base de données est un enfant du serveur.

"resources": [
  {
    "type": "Microsoft.Sql/servers",
    "apiVersion": "2022-05-01-preview",
    "name": "[parameters('serverName')]",
    "location": "[parameters('location')]",
    "properties": {
      "administratorLogin": "[parameters('administratorLogin')]",
      "administratorLoginPassword": "[parameters('administratorLoginPassword')]"
    },
    "resources": [
      {
        "type": "databases",
        "apiVersion": "2022-05-01-preview",
        "name": "[parameters('sqlDBName')]",
        "location": "[parameters('location')]",
        "sku": {
          "name": "Standard",
          "tier": "Standard"
          },
        "dependsOn": [
          "[resourceId('Microsoft.Sql/servers', parameters('serverName'))]"
        ]
      }
    ]
  }
]

Pour obtenir le modèle complet, consultez Modèle de démarrage rapide pour Azure SQL Database.

fonctions reference et list

La fonction de référence permet à une expression de tirer sa valeur d’un autre nom JSON et de paires de valeurs ou de ressources runtime. Les fonctions list* renvoient les valeurs d’une ressource à partir d’une opération de liste.

Les expressions de référence et de liste déclarent implicitement qu’une ressource dépend d’une autre. Si possible, utilisez une référence implicite pour éviter d’ajouter une dépendance inutile.

Pour appliquer une dépendance implicite, reportez-vous à la ressource par son nom, et non par son ID de ressource. Si vous transmettez l’ID de ressource dans les fonctions reference ou list, une référence implicite n’est pas créée.

Le format général de la fonction reference est :

reference('resourceName').propertyPath

Le format général de la fonction listKeys est :

listKeys('resourceName', 'yyyy-mm-dd')

Dans l’exemple suivant, un point de terminaison CDN dépend explicitement du profil CDN et implicitement d’une application web.

{
    "type": "endpoints",
    "apiVersion": "2021-06-01",
    "name": "[variables('endpointName')]",
    "location": "[resourceGroup().location]",
    "dependsOn": [
      "[variables('profileName')]"
    ],
    "properties": {
      "originHostHeader": "[reference(variables('webAppName')).hostNames[0]]",
      ...
    }
    ...
}

Pour plus d’informations, consultez la fonction de référence.

En fonction des ressources dans une boucle

Pour déployer des ressources qui dépendent des ressources d’une boucle de copie, deux options s’offrent à vous. Vous pouvez définir une dépendance sur des ressources individuelles dans la boucle ou sur l’ensemble de la boucle.

Notes

Dans la plupart des cas, vous devez définir la dépendance sur des ressources individuelles au sein de la boucle de copie. N’utilisez l’ensemble de la boucle lorsque vous avez besoin que toutes les ressources de la boucle existent avant de créer la ressource suivante. La définition de la dépendance sur l’ensemble de la boucle entraîne une expansion importante du graphique des dépendances, surtout si ces ressources en boucle dépendent d’autres ressources. Cette expansion des dépendances entrave l’efficacité du déploiement.

L’exemple suivant montre comment déployer plusieurs machines virtuelles. Le modèle crée le même nombre d’interfaces réseau. Chaque ordinateur virtuel dépend d’une seule interface réseau, et non de l’ensemble de la boucle.

{
  "type": "Microsoft.Network/networkInterfaces",
  "apiVersion": "2022-07-01",
  "name": "[format('{0}-{1}', variables('nicPrefix'), copyIndex())]",
  "location": "[parameters('location')]",
  "copy": {
    "name": "nicCopy",
    "count": "[parameters('vmCount')]"
  },
  ...
},
{
  "type": "Microsoft.Compute/virtualMachines",
  "apiVersion": "2022-11-01",
  "name": "[format('{0}{1}', variables('vmPrefix'), copyIndex())]",
  "location": "[parameters('location')]",
  "dependsOn": [
    "[resourceId('Microsoft.Network/networkInterfaces',format('{0}-{1}', variables('nicPrefix'),copyIndex()))]"
  ],
  "copy": {
    "name": "vmCopy",
    "count": "[parameters('vmCount')]"
  },
  "properties": {
    "networkProfile": {
      "networkInterfaces": [
        {
          "id": "[resourceId('Microsoft.Network/networkInterfaces',format('(0)-(1)', variables('nicPrefix'), copyIndex()))]",
          "properties": {
            "primary": "true"
          }
        }
      ]
    },
    ...
  }
}

L’exemple suivant montre comment déployer trois comptes de stockage avant de déployer la machine virtuelle. Notez que le nom de l’élément copy a name défini sur storagecopy et que l’élément dependsOn de la machine virtuelle est également défini sur storagecopy.

{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "location": {
      "type": "string",
      "defaultValue": "[resourceGroup().location]"
    }
  },
  "resources": [
    {
      "type": "Microsoft.Storage/storageAccounts",
      "apiVersion": "2022-09-01",
      "name": "[format('{0}storage{1}, copyIndex(), uniqueString(resourceGroup().id))]",
      "location": "[parameters('location')]",
      "sku": {
        "name": "Standard_LRS"
      },
      "kind": "Storage",
      "copy": {
        "name": "storagecopy",
        "count": 3
      },
      "properties": {}
    },
    {
      "type": "Microsoft.Compute/virtualMachines",
      "apiVersion": "2022-11-01",
      "name": "[format('VM{0}', uniqueString(resourceGroup().id))]",
      "dependsOn": ["storagecopy"],
      ...
    }
  ]
}

Les noms symboliques peuvent être utilisés dans les tableaux dependsOn. Si un nom symbolique est destiné à une boucle de copie, toutes les ressources de la boucle sont ajoutées comme dépendances. L’exemple précédent peut être écrit comme le JSON suivant. Dans l’exemple, myVM dépend des comptes de stockage dans la boucle myStorages.

{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "languageVersion": "2.0",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "location": {
      "type": "string",
      "defaultValue": "[resourceGroup().location]"
    }
  },
  "resources": {
    "myStorages": {
      "type": "Microsoft.Storage/storageAccounts",
      "apiVersion": "2022-09-01",
      "name": "[format('{0}storage{1}, copyIndex(), uniqueString(resourceGroup().id))]",
      "location": "[parameters('location')]",
      "sku": {
        "name": "Standard_LRS"
      },
      "kind": "Storage",
      "copy": {
        "name": "storagecopy",
        "count": 3
      },
      "properties": {}
    },
    "myVM": {
      "type": "Microsoft.Compute/virtualMachines",
      "apiVersion": "2022-11-01",
      "name": "[format('VM{0}', uniqueString(resourceGroup().id))]",
      "dependsOn": ["myStorages"],
      ...
    }
  }
}

Dépendances circulaires

Resource Manager identifie les dépendances circulaires lors de la validation du modèle. Si vous recevez une erreur indiquant qu’il existe une dépendance circulaire, évaluez votre modèle pour voir si certaines dépendances peuvent être supprimées. Si la suppression de ces dépendances n’a aucun effet, vous pouvez éliminer les dépendances circulaires en déplaçant certaines opérations de déploiement dans les ressources enfants. Déployez les ressources enfants après les ressources présentant la dépendance circulaire. Par exemple, supposons que vous déployiez deux machines virtuelles, mais que vous deviez définir sur chacune d’elles des propriétés faisant référence les unes aux autres. Vous pouvez les déployer dans l’ordre suivant :

  1. Machine virtuelle 1
  2. Machine virtuelle 2
  3. L’extension sur la machine virtuelle 1 dépend des machines virtuelles 1 et 2. L’extension définit sur la machine virtuelle 1 des valeurs qu’elle obtient de la machine virtuelle 2.
  4. L’extension sur la machine virtuelle 2 dépend des machines virtuelles 1 et 2. L’extension définit sur la machine virtuelle 2 des valeurs qu’elle obtient de la machine virtuelle 1.

Pour plus d’informations sur l’évaluation de l’ordre de déploiement et la résolution des erreurs de dépendance, consultez l’article Résolution des erreurs courantes dans des déploiements Azure avec Azure Resource Manager.

Étapes suivantes