Confronto tra JSON e Bicep per i modelli

Questo articolo confronta la sintassi Bicep con la sintassi JSON per i modelli di Azure Resource Manager (modelli di Resource Manager). Nella maggior parte dei casi Bicep fornisce una sintassi minore rispetto all'equivalente in JSON.

Se si ha familiarità con l'uso di JSON per sviluppare modelli di Resource Manager, usare gli esempi seguenti per informazioni sulla sintassi equivalente per Bicep.

Confrontare i file completi

Bicep Playground consente di visualizzare il lato JSON Bicep e equivalente. È possibile confrontare le implementazioni della stessa infrastruttura.

Ad esempio, è possibile visualizzare il file per distribuire un server SQL e un database. Bicep è circa la metà delle dimensioni del modello di Resource Manager.

Screenshot dei modelli affiancati

Espressioni

Per creare un'espressione:

func()
"[func()]"

Parametri

Per dichiarare un parametro con un valore predefinito:

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

Per ottenere un valore di parametro, usare il nome definito:

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

Variabili

Per dichiarare una variabile:

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

Per ottenere un valore di variabile, usare il nome definito:

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

Stringhe

Per concatenare stringhe:

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

Operatori logici

Per restituire l'AND logico:

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

Per impostare in modo condizionale un valore:

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

Ambito della distribuzione

Per impostare l'ambito di destinazione della distribuzione:

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

Risorse

Per dichiarare una risorsa:

resource virtualMachine 'Microsoft.Compute/virtualMachines@2023-03-01' = {
  ...
}
"resources": [
  {
    "type": "Microsoft.Compute/virtualMachines",
    "apiVersion": "2020-06-01",
    ...
  }
]

Per distribuire in modo condizionale una risorsa:

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

Per impostare una proprietà di risorsa:

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

Per ottenere l'ID risorsa di una risorsa nel modello:

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

Loop

Per eseguire l'iterazione degli elementi in una matrice o conteggio:

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

Dipendenze delle risorse

Per Bicep è possibile impostare una dipendenza esplicita, ma questo approccio non è consigliato. Si basano invece sulle dipendenze implicite. Una dipendenza implicita viene creata quando una dichiarazione di risorsa fa riferimento all'identificatore di un'altra risorsa.

Di seguito viene illustrata un'interfaccia di rete con una dipendenza implicita da un gruppo di sicurezza di rete. Fa riferimento al gruppo di sicurezza di rete con netSecurityGroup.id.

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

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

Se è necessario impostare una dipendenza esplicita, usare:

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

Risorse di riferimento

Per ottenere una proprietà da una risorsa nel modello:

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

Per ottenere una proprietà da una risorsa esistente non distribuita nel modello:

resource storageAccount 'Microsoft.Storage/storageAccounts@2022-09-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]"

In Bicep usare la funzione di accesso nidificata (::) per ottenere una proprietà in una risorsa annidata all'interno di una risorsa padre:

VNet1::Subnet1.properties.addressPrefix

Per JSON, usare la funzione di riferimento:

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

Output

Per restituire una proprietà da una risorsa nel modello:

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

Per restituire in modo condizionale un valore:

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'operatore ternario Bicep è l'equivalente alla funzione se in un codice JSON del modello arm, non la proprietà condition. La sintassi ternaria deve valutare un valore o l'altro. Se la condizione è false negli esempi precedenti, Bicep restituisce un nome host con una stringa vuota, ma JSON non restituisce valori.

Riutilizzo del codice

Per separare una soluzione in più file:

Passaggi successivi