下边就来实际感觉下BICEP的上手体验,首先来对比下ARM Template和BICEP的基础语法,对比完了就能感受到BICEP的语法有多简洁了
定义参数
BICEP
param demoParam string = 'Contoso'ARM Template
"parameters": {
  "demoParam": {
    "type": "string",
    "defaultValue": "param"
  }
}字符串拼接
BICEP
'${prefix}-vm-{suffix}'ARM Template
[concat(parameters('prefix'), '-vm', parameters('suffix'))]获取部署资源的属性
BICEP
nic1.idARM Template
[resourceId('Microsoft.Network/networkInterfaces', variables('nic1Name'))]其他的例子还有很多,不过我想这几个应该已经足够有说服力了,可以发现BICEP的语法更偏向于编程语言,给用户的亲和度更高,而如果想实际用BICEP部署一些资源的话,可以先从最简单的说起
首先来部署一个VNET,其中可以包括几个subnet
先把代码准备好,可以发现代码其实都很简单,要比同等级别下ARM Template的代码简单很多,和Terraform非常类似,尤其是resource声明那里
@description('Name of VNET')
param vnetName string = 'BICEP-VNET'
@description('name of subnet')
param subnetName string = 'appsubnet'
@description('ip range of subnet')
param vnetIPRange string = '10.10.0.0/16'
@description('ip range of subnet')
param subnetIPRange string = '10.10.0.0/24'
@description('location which vnet should be deployed')
param location string = resourceGroup().location
resource virtualNetwork 'Microsoft.Network/virtualNetworks@2021-05-01' = {
  name: vnetName
  location: location
  properties: {
    addressSpace: {
      addressPrefixes: [
        vnetIPRange
      ]
    }
    subnets: [
      {
        name: subnetName
        properties: {
          addressPrefix: subnetIPRange
        }
      }
    ]
  }
}代码准备好之后就可以开始部署了,部署的方式和ARM Template是完全一样的,运行的命令都是之前的命令,所有动作都是后台完成的,无需用户干涉,前提是你的AZ CLI或者PowerShell版本一定要够
这里用CLI举例,首先可以用whatif来看下部署之后会发生什么,这个输出结果看起来还是挺清爽的,看着和Terraform plan或者GIT的输出差不多
az deployment group what-if --template-file .\main.bicep --resource-group bicep
接下来就可以实际部署了
az deployment group create --template-file .\main.bicep --resource-group bicep
部署的过程相当快,毕竟只是部署了一个VNET,很快在portal就可以看到了

以上只是最原始的用法,还可以用一些更复杂的语法,比如使用if进行条件判断,使用object类型的变量以及secure string等
代码
@description('location which VM should be deployed')
param location string = resourceGroup().location
@description('username of vm')
param vmUserName string='vmadmin'
@description('pwd of vm')
@secure()
param vmPwd string
@description('vm tag')
param vmTag object = {
  EnvironmentName: 'Prod'
  Dept: 'Finance'
  CreateBy: 'BICEP'
}
@description('Env')
param Env string = 'Prod'
resource NIC 'Microsoft.Network/networkInterfaces@2020-11-01' = {
  name: 'vmNic'
  location: location
  properties: {
    ipConfigurations: [
      {
        name: 'IP'
        properties: {
          privateIPAllocationMethod: 'Dynamic'
          subnet: {
            id: resourceId('Microsoft.Network/virtualNetworks/subnets','BICEP-VNET','appsubnet')
          }
        }
      }
    ]
  }
}
resource ubuntuVM 'Microsoft.Compute/virtualMachines@2020-12-01' = {
  name: 'BICEPVM'
  location: location
  tags:vmTag
  properties: {
    hardwareProfile: {
      vmSize: 'Standard_B1ms'
    }
    osProfile: {
      computerName: 'BICEPVM'
      adminUsername: vmUserName
      adminPassword: vmPwd
    }
    storageProfile: {
      imageReference: {
        publisher: 'Canonical'
        offer: 'UbuntuServer'
        sku: '16.04-LTS'
        version: 'latest'
      }
      osDisk: {
        name: 'OS-DISK'
        caching: 'ReadWrite'
        createOption: 'FromImage'
      }
    }
    networkProfile: {
      networkInterfaces: [
        {
          //隐式关联
          id: NIC.id
        }
      ]
    }
  }
}
resource storageaccount 'Microsoft.Storage/storageAccounts@2021-02-01' = if(Env == 'Prod') {
  name: 'sa${take(uniqueString(resourceGroup().id),10)}'
  location: location
  kind: 'StorageV2'
  sku: {
    name: 'Standard_LRS'
  }
}
output vmIP string = NIC.properties.ipConfigurations[0].properties.privateIPAddresswhatif进行检查
az deployment group what-if --template-file .\main.bicep --resource-group bicep --parameters Env='Dev'这里会要求输入pwd,因为是secure string,所以输入时也不会显示

因为指定了parameter是DEV,所以storage account没有部署

如果不指定env,使用模板中定义的Prod进行部署,则会部署storage account
az deployment group what-if --template-file .\main.bicep --resource-group bicep最终部署
az deployment group create --template-file .\main.bicep --resource-group bicep
Tag也出来了











