Compartilhar via


Comparando JSON e Bicep para modelos

Este artigo compara a sintaxe Bicep com a sintaxe JSON para modelos do ARM (Azure Resource Manager). 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 do ARM, use os exemplos a seguir para saber mais sobre a sintaxe equivalente para o Bicep.

Comparar arquivos completos

O Bicep Playground permite exibir 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 tela 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 variável, use o nome que você definiu:

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

Cordas

Para concatenar cadeias de caracteres:

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

Operadores lógicos

Para retornar a lógica AND:

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

Para definir condicionalmente um valor:

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

Escopo da implantaçã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 do recurso de um recurso no modelo:

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

Loops

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 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.

O exemplo a seguir mostra uma interface de rede com uma dependência implícita de 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 é 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]"

No 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 do Bicep é o equivalente à função if em um JSON de modelo ARM, e não à propriedade de condição. A sintaxe ternária deve ser avaliada como um valor ou outro. Se a condição for falsa nos exemplos anteriores, o Bicep produzirá um nome de host com uma cadeia de caracteres vazia, mas JSON não produzirá valores.

Reutilização de código

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

Próximas etapas