Сравнение JSON и Bicep для шаблонов

В этой статье сравнивается синтаксис Bicep с синтаксисом JSON для шаблонов Azure Resource Manager (шаблоны ARM). В большинстве случаев Bicep предоставляет синтаксис, который менее многословный, чем эквивалент в JSON.

Если вы знакомы с использованием JSON для разработки шаблонов ARM, воспользуйтесь следующими примерами, чтобы узнать об эквивалентном синтаксисе для Bicep.

Сравнение полных файлов

Тестовая площадка Bicep позволяет сопоставить файл Bicep и его эквивалент в формате JSON. Вы можете сравнить реализацию одной и той же инфраструктуры.

Например, можно просмотреть файл для развертывания SQL Server и базы данных. Файла Bicep примерно в два раза меньше шаблона ARM.

Снимок экрана: параллельные шаблоны

Выражения

Чтобы создать выражение:

func()
"[func()]"

Параметры

Чтобы объявить параметр со значением по умолчанию:

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

Чтобы получить значение параметра, используйте определенное вами имя:

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

Переменные

Чтобы объявить переменную:

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

Чтобы получить значение переменной, используйте определенное вами имя:

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

Строки

Чтобы сцепить строки:

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

Логические операторы

Чтобы вернуть логическое И:

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

Чтобы условно задать значение:

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

Область развертывания

Чтобы задать целевую область развертывания:

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

Ресурсы

Чтобы объявить ресурс:

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

Чтобы выполнить условное развертывание ресурса:

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

Чтобы задать свойство ресурса:

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

Чтобы получить идентификатор ресурса в шаблоне:

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

Циклы

Чтобы выполнить итерации по элементам массива или счетчика:

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

Зависимости ресурсов

Для Bicep можно задать явную зависимость, но такой подход не рекомендуется. Вместо этого используйте неявные зависимости. Неявная зависимость создается, когда одно объявление ресурса ссылается на идентификатор другого ресурса.

Ниже показан сетевой интерфейс с неявной зависимостью от группы безопасности сети. Он ссылается на группу безопасности сети с помощью 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
    }
  }
}

Если необходимо задать явную зависимость:

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

Справочные ресурсы

Чтобы получить свойство из ресурса в шаблон:

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

Чтобы получить свойство из существующего ресурса, который не развернут в шаблоне:

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

В Bicep используйте вложенный метод доступа (::) для получения свойства ресурса, вложенного в родительский ресурс:

VNet1::Subnet1.properties.addressPrefix

Для JSON используйте ссылочную функцию:

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

Выходные данные

Чтобы вывести свойство из ресурса в шаблон:

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

Чтобы условно вывести значение:

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

Тернарный оператор Bicep эквивалентен функции if в шаблоне ARM JSON, а не свойству условия. Тернарный синтаксис должен вычислить одно из двух значений. Если в предыдущих примерах условие ложно, Bicep выводит имя узла с пустой строкой, а JSON не выводит никаких значений.

Повторное использование кода

Чтобы разделить решения на несколько файлов:

Дальнейшие действия