Partilhar via


Comparando JSON e Bicep para modelos

Este artigo compara a sintaxe Bicep com a sintaxe JSON para modelos do Azure Resource Manager (modelos ARM). Na maioria dos casos, o Bicep fornece sintaxe menos detalhada do que o equivalente em JSON.

Se você estiver familiarizado com o uso de JSON para desenvolver modelos ARM, use os exemplos a seguir para aprender sobre a sintaxe equivalente para Bicep.

Comparar ficheiros completos

O Bicep Playground permite visualizar o Bicep e o JSON equivalente lado a lado. Você pode comparar as implementações da mesma infraestrutura.

Por exemplo, você pode exibir o arquivo para implantar um servidor SQL e um banco de dados. O bíceps tem cerca de metade do tamanho do modelo ARM.

Captura de ecrã de modelos lado a lado

Expressões

Para criar uma expressão:

func()
"[func()]"

Parâmetros

Para declarar um parâmetro com um valor padrão:

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

Para obter um valor de parâmetro, use o nome que você definiu:

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

Variáveis

Para declarar uma variável:

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

Para obter um valor de variável, use o nome definido:

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

Cordas

Para concatenar cadeias de caracteres:

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

Operadores lógicos

Para retornar o AND lógico:

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

Para definir condicionalmente um valor:

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

Âmbito da implementação

Para definir o escopo de destino da implantação:

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

Recursos

Para declarar um recurso:

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

Para implantar condicionalmente um recurso:

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

Para definir uma propriedade de recurso:

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

Para obter o ID de um recurso no modelo:

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

Laços

Para iterar sobre itens em uma matriz ou contagem:

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

Dependências de recursos

Para o Bicep, você pode definir uma dependência explícita, mas essa abordagem não é recomendada. Em vez disso, confie em dependências implícitas. Uma dependência implícita é criada quando uma declaração de recurso faz referência ao identificador de outro recurso.

A seguir mostra uma interface de rede com uma dependência implícita em um grupo de segurança de rede. Ele faz referência ao grupo de segurança de rede com netSecurityGroup.id.

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

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

Se você precisar definir uma dependência explícita, use:

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

Recursos de referência

Para obter uma propriedade de um recurso no modelo:

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

Para obter uma propriedade de um recurso existente que não está implantado no modelo:

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

Em Bicep, use o acessador aninhado (::) para obter uma propriedade em um recurso aninhado dentro de um recurso pai:

VNet1::Subnet1.properties.addressPrefix

Para JSON, use a função de referência:

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

Saídas

Para gerar uma propriedade de um recurso no modelo:

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

Para gerar condicionalmente um valor:

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

O operador ternário Bicep é o equivalente à função if em um modelo ARM JSON, não a propriedade condition. A sintaxe ternária tem que avaliar para um valor ou outro. Se a condição for false nos exemplos anteriores, o Bicep gerará um nome de host com uma cadeia de caracteres vazia, mas o JSON não produzirá valores.

Reutilização de código

Para separar uma solução em vários ficheiros:

Próximos passos