按条件部署资源

已完成

可以在 Bicep 代码中使用条件,仅在存在特定约束时部署资源。

例如,在你所在的玩具公司,需要将资源部署到各种环境。 在将资源部署到生产环境时,需要确保为 Azure SQL 逻辑服务器启用审核。 但是,在将资源部署到开发环境时,不需要启用审核。 你需要使用单个模板将资源部署到所有环境。

在本单元中,你将了解如何按条件部署资源。

使用基本条件

在 Bicep 中部署资源时,可以提供 if 关键字,后跟一个条件。 此条件应求值为一个布尔值(true 或 false)。 如果值为 true,则部署资源。 如果值为 false,则不部署资源。

通常,根据你提供的参数值来创建条件。 例如,以下代码仅在 deployStorageAccount 参数设置为 true 时部署存储帐户:

param deployStorageAccount bool

resource storageAccount 'Microsoft.Storage/storageAccounts@2023-05-01' = if (deployStorageAccount) {
  name: 'teddybearstorage'
  location: resourceGroup().location
  kind: 'StorageV2'
  // ...
}

请注意,if 关键字与资源定义位于同一行。

使用表达式作为条件

前面的示例是一个很基本的示例。 deployStorageAccount 参数的类型为 bool,因此,它的值是 true 还是 false 就一目了然了。

在 Bicep 中,条件还可以包括表达式。 在下面的示例中,代码仅在 environmentName 参数值等于 Production 时部署 SQL 审核资源:

@allowed([
  'Development'
  'Production'
])
param environmentName string

resource auditingSettings 'Microsoft.Sql/servers/auditingSettings@2023-08-01-preview' = if (environmentName == 'Production') {
  parent: server
  name: 'default'
  properties: {
  }
}

通常,最好是为用作条件的表达式创建一个变量。 这样,模板就更易于理解和读取。 下面是一个示例:

@allowed([
  'Development'
  'Production'
])
param environmentName string

var auditingEnabled = environmentName == 'Production'

resource auditingSettings 'Microsoft.Sql/servers/auditingSettings@2023-08-01-preview' = if (auditingEnabled) {
  parent: server
  name: 'default'
  properties: {
  }
}

依赖于按条件部署的资源

当你按条件部署资源时,有时需要知道 Bicep 如何评估资源之间的依赖关系。

我们来继续编写一些 Bicep 代码用于部署 SQL 审核设置。 Bicep 文件还需要声明一个存储帐户资源,如下所示:

@allowed([
  'Development'
  'Production'
])
param environmentName string
param location string = resourceGroup().location
param auditStorageAccountName string = 'bearaudit${uniqueString(resourceGroup().id)}'

var auditingEnabled = environmentName == 'Production'
var storageAccountSkuName = 'Standard_LRS'

resource auditStorageAccount 'Microsoft.Storage/storageAccounts@2023-05-01' = if (auditingEnabled) {
  name: auditStorageAccountName
  location: location
  sku: {
    name: storageAccountSkuName
  }
  kind: 'StorageV2'
}

resource auditingSettings 'Microsoft.Sql/servers/auditingSettings@2023-08-01-preview' = if (auditingEnabled) {
  parent: server
  name: 'default'
  properties: {
  }
}

请注意,存储帐户也有一个条件。 这意味着它也不会部署到非生产环境。 SQL 审核设置资源现在可以引用存储帐户的详细信息:

resource auditingSettings 'Microsoft.Sql/servers/auditingSettings@2023-08-01-preview' = if (auditingEnabled) {
  parent: server
  name: 'default'
  properties: {
    state: 'Enabled'
    storageEndpoint: environmentName == 'Production' ? auditStorageAccount.properties.primaryEndpoints.blob : ''
    storageAccountAccessKey: environmentName == 'Production' ? listKeys(auditStorageAccount.id, auditStorageAccount.apiVersion).keys[0].value : ''
  }
}

请注意,此 Bicep 代码在 storageEndpointstorageAccountAccessKey 属性内使用问号 (?) 运算符。 将 Bicep 代码部署到生产环境时,表达式将被求值为存储帐户中的详细信息。 将代码部署到非生产环境时,表达式的计算结果是空字符串 ('')。

你可能想知道为什么需要此代码,因为 auditingSettingsauditStorageAccount 都具有相同的条件,所以你永远不需要部署一个没有存储帐户的 SQL 审核设置资源。 虽然这是事实,但 Azure 资源管理器会在资源的条件语句之前计算属性表达式。 这意味着如果 Bicep 代码没有此表达式,部署将失败,并出现 ResourceNotFound 错误。

注意

不能在同一 Bicep 文件中定义同名的两个资源,然后按条件仅部署其中一个资源。 部署将失败,因为资源管理器将此操作视为冲突。

如果你有多个资源,所有这些资源都具有相同的部署条件,请考虑使用 Bicep 模块。 可以创建一个用于部署所有资源的模块,然后在主 Bicep 文件中对模块声明设置一个条件。