比较模板的 JSON 和 Bicep

本文将 Azure 资源管理器模板(ARM 模板)的 Bicep 语法与 JSON 语法进行了比较。 在大多数情况下,Bicep 提供的语法比 JSON 中的等效语法更简单。

如果你知道如何使用 JSON 开发 ARM 模板,请使用以下示例来了解 Bicep 的等效语法。

比较完整文件

Bicep 操场可让你并排查看 Bicep 和等效 JSON。 可以比较同一基础结构的实现。

例如,可以查看文件以部署 SQL 服务器和数据库。 Bicep 大约是 ARM 模板大小的一半。

Screenshot of side by side templates

表达式

若要创作表达式,请运行以下命令:

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

逻辑运算符

若要返回逻辑 AND,请运行以下命令:

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@2020-06-01' = {
  ...
}
"resources": [
  {
    "type": "Microsoft.Compute/virtualMachines",
    "apiVersion": "2020-06-01",
    ...
  }
]

若要按条件部署资源,请运行以下命令:

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

若要设置资源属性,请运行以下命令:

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

若要获取模板中资源的资源 ID,请运行以下命令:

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@2020-06-01' = {
  ...
}

resource nic1 'Microsoft.Network/networkInterfaces@2020-06-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@2019-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]"

在 Bicep 中,使用 嵌套访问器 (::) 获取父资源中嵌套的资源的属性:

VNet1::Subnet1.properties.addressPrefix

对于 JSON,请使用 reference 函数:

[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 三元运算符等效于 ARM 模板 JSON 中的 if 函数,而不是 condition 属性。 三元语法的计算结果必须为一个值或另一个值。 如果前面示例中的条件为 false,则 Bicep 会输出一个带有空字符串的主机名,但 JSON 不会输出任何值。

代码重用

若要将解决方案隔离到多个文件,请运行以下命令:

后续步骤