Partager via


Comparaison de JSON et Bicep pour les modèles

Cet article compare la syntaxe Bicep à la syntaxe JSON pour les modèles Azure Resource Manager (modèles ARM). Dans la plupart des cas, Bicep fournit une syntaxe moins détaillée que l’équivalent au format JSON.

Si vous êtes familiarisé avec l’utilisation de JSON pour développer des modèles ARM, utilisez les exemples suivants pour en savoir plus sur la syntaxe équivalente pour Bicep.

Comparer les fichiers complets

Le Bicep Playground vous permet d’afficher Bicep et l'équivalent JSON côte à côte. Vous pouvez comparer les implémentations de la même infrastructure.

Par exemple, vous pouvez afficher le fichier pour déployer un serveur SQL et une base de données. Bicep fait environ la moitié de la taille du modèle ARM.

Capture d’écran de modèles côte à côte

Expressions

Pour créer une expression :

func()
"[func()]"

Paramètres

Pour déclarer un paramètre avec une valeur par défaut :

param orgName string = 'Contoso'
"parameters": {
  "orgName": {
    "type": "string",
    "defaultValue": "Contoso"
  }
}

Pour obtenir une valeur de paramètre, utilisez le nom que vous avez défini :

name: orgName
"name": "[parameters('orgName')]"

Variables

Pour déclarer une variable :

var description = 'example value'
"variables": {
  "description": "example value"
}

Pour obtenir une valeur de variable, utilisez le nom que vous avez défini :

workloadSetting: description
"workloadSetting": "[variables('description')]"

Chaînes

Pour concaténer des chaînes :

name: '${namePrefix}-vm'
"name": "[concat(parameters('namePrefix'), '-vm')]"

Opérateurs logiques

Pour retourner l’opérateur logique AND :

isMonday && isNovember
[and(parameter('isMonday'), parameter('isNovember'))]

Pour définir conditionnellement une valeur :

isMonday ? 'valueIfTrue' : 'valueIfFalse'
[if(parameters('isMonday'), 'valueIfTrue', 'valueIfFalse')]

Étendue du déploiement

Pour définir l’étendue cible du déploiement :

targetScope = 'subscription'
"$schema": "https://schema.management.azure.com/schemas/2018-05-01/subscriptionDeploymentTemplate.json#"

Ressources

Pour déclarer une ressource :

resource virtualMachine 'Microsoft.Compute/virtualMachines@2025-04-01' = {
  ...
}
"resources": [
  {
    "type": "Microsoft.Compute/virtualMachines",
    "apiVersion": "2024-03-01",
    ...
  }
]

Pour déployer une ressource de manière conditionnelle :

resource virtualMachine 'Microsoft.Compute/virtualMachines@2025-04-01' = if(deployVM) {
  ...
}
"resources": [
  {
    "condition": "[parameters('deployVM')]",
    "type": "Microsoft.Compute/virtualMachines",
    "apiVersion": "2024-03-01",
    ...
  }
]

Pour définir une propriété de ressource :

sku: '2016-Datacenter'
"sku": "2016-Datacenter",

Pour obtenir l’ID de ressource d’une ressource dans le modèle :

nic1.id
[resourceId('Microsoft.Network/networkInterfaces', variables('nic1Name'))]

Boucles

Pour itérer sur les éléments d’un tableau ou d’un nombre :

[for storageName in storageAccountNames: {
  ...
}]
"copy": {
  "name": "storagecopy",
  "count": "[length(parameters('storageAccountNames'))]"
},
...

Dépendances des ressources

Pour Bicep, vous pouvez définir une dépendance explicite, mais cette approche n’est pas recommandée. Au lieu de cela, reposez sur des dépendances implicites. Une dépendance implicite est créée lorsqu’une déclaration de ressource fait référence à l’identificateur d’une autre ressource.

L’exemple suivant montre une interface réseau avec une dépendance implicite sur un groupe de sécurité réseau. Il fait référence au groupe de sécurité réseau avec netSecurityGroup.id.

resource netSecurityGroup 'Microsoft.Network/networkSecurityGroups@2025-01-01' = {
  ...
}

resource nic1 'Microsoft.Network/networkInterfaces@2025-01-01' = {
  name: nic1Name
  location: location
  properties: {
    ...
    networkSecurityGroup: {
      id: netSecurityGroup.id
    }
  }
}

Si vous devez définir une dépendance explicite, utilisez :

dependsOn: [ storageAccount ]
"dependsOn": ["[resourceId('Microsoft.Storage/storageAccounts', 'parameters('storageAccountName'))]"]

Ressources de référence

Pour obtenir une propriété à partir d’une ressource dans le modèle :

storageAccount.properties.primaryEndpoints.blob
[reference(resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountName'))).primaryEndpoints.blob]

Pour obtenir une propriété à partir d’une ressource existante qui n’est pas déployée dans le modèle :

resource storageAccount 'Microsoft.Storage/storageAccounts@2025-06-01' existing = {
  name: storageAccountName
}

// use later in template as often as needed
storageAccount.properties.primaryEndpoints.blob
// required every time the property is needed
"[reference(resourceId('Microsoft.Storage/storageAccounts/', parameters('storageAccountName')), '2019-06-01').primaryEndpoints.blob]"

Dans Bicep, utilisez l’accesseur imbriqué (::) pour obtenir une propriété sur une ressource imbriquée dans une ressource parente :

VNet1::Subnet1.properties.addressPrefix

Pour JSON, utilisez la fonction de référence :

[reference(resourceId('Microsoft.Network/virtualNetworks/subnets', variables('subnetName'))).properties.addressPrefix]

Sorties

Pour générer une propriété à partir d’une ressource dans le modèle :

output hostname string = publicIP.properties.dnsSettings.fqdn
"outputs": {
  "hostname": {
    "type": "string",
    "value": "[reference(resourceId('Microsoft.Network/publicIPAddresses', variables('publicIPAddressName'))).dnsSettings.fqdn]"
  },
}

Pour générer une valeur de manière conditionnelle :

output hostname string = condition ? publicIP.properties.dnsSettings.fqdn : ''
"outputs": {
  "hostname": {
    "condition": "[variables('condition')]",
    "type": "string",
    "value": "[reference(resourceId('Microsoft.Network/publicIPAddresses', variables('publicIPAddressName'))).dnsSettings.fqdn]"
  }
}

L’opérateur ternaire Bicep équivaut à la fonction if dans un json de modèle ARM, et non à la propriété de condition. La syntaxe ternaire doit évaluer une valeur ou l’autre. Si la condition est false dans les exemples précédents, Bicep génère un nom d’hôte avec une chaîne vide, mais JSON ne génère aucune valeur.

Réutilisation du code

Pour séparer une solution en plusieurs fichiers :

Étapes suivantes