你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn

比较模板的 JSON 和 Bicep

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

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

比较完整文件

Bicep Playground 允许你并排查看 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')]"

逻辑运算符

若要返回逻辑 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@2024-03-01' = {
  ...
}
"resources": [
  {
    "type": "Microsoft.Compute/virtualMachines",
    "apiVersion": "2024-03-01",
    ...
  }
]

若要有条件地部署资源,请执行以下操作:

resource virtualMachine 'Microsoft.Compute/virtualMachines@2024-03-01' = if(deployVM) {
  ...
}
"resources": [
  {
    "condition": "[parameters('deployVM')]",
    "type": "Microsoft.Compute/virtualMachines",
    "apiVersion": "2024-03-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@2024-05-01' = {
  ...
}

resource nic1 'Microsoft.Network/networkInterfaces@2024-05-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@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]"

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

代码重用

将解决方案分成多个文件:

后续步骤