逻辑参数模式

可以使用参数指定某个资源的逻辑定义,甚至是多个资源的逻辑定义。 Bicep 文件可将逻辑参数转换为可部署的资源定义。 通过遵循此模式,可以将部署内容与部署方式分开 。

上下文和问题

在复杂部署中,数组参数和循环用于创建一组资源或资源属性。 如果创建定义资源详细信息的参数,则创建的参数将难以理解和使用。

解决方案

定义接受简化值,或特定于业务域而不是特定于 Azure 资源的值的参数。 将逻辑生成到 Bicep 文件中,以将简化值转换为 Azure 资源定义。

通常,将使用循环将参数中定义的逻辑值转换为资源定义预期的属性值。

使用此模式时,可以轻松为不需要在资源之间更改的属性应用默认值。 还可以使用变量函数根据自己的业务规则自动确定资源属性的值。

通过使用逻辑参数模式,可以部署复杂的资源集,同时使模板的参数保持简单和易于使用。

示例 1:虚拟网络子网

此示例演示如何使用该模式来简化新子网的定义,并添加确定资源配置的业务逻辑。

此示例定义了一个参数,该参数指定应在虚拟网络中创建的子网的列表。 每个子网的定义还包括一个名为 allowRdp 的属性。 此属性指示子网是否应与允许入站远程桌面流量的网络安全组关联:

param subnets array = [
  {
    name: 'Web'
    addressPrefix: '10.0.0.0/24'
    allowRdp: false
  }
  {
    name: 'JumpBox'
    addressPrefix: '10.0.1.0/24'
    allowRdp: true
  }
]

然后,Bicep 文件定义一个变量,将每个逻辑子网定义转换为 Azure 所需的子网定义。 当 allowRdp 属性设置为 true 时,网络安全组被分配给子网。

var subnetsToCreate = [for item in subnets: {
  name: item.name
  properties: {
    addressPrefix: item.addressPrefix
    networkSecurityGroup: item.allowRdp ? {
       id: nsgAllowRdp.id
    } : null
  }
}]

最后,Bicep 文件定义虚拟网络,并使用变量来配置子网:

resource virtualNetwork 'Microsoft.Network/virtualNetworks@2019-11-01' = {
  name: virtualNetworkName
  location: location
  properties: {
    addressSpace: {
      addressPrefixes: [
        virtualNetworkAddressPrefix
      ]
    }
    subnets: subnetsToCreate
  }
}

请参阅完整示例。

示例 2:服务总线队列

此示例演示如何使用该模式在基于参数定义的多个资源中应用一组一致的配置。

本示例使用 Azure 服务总线队列的队列名称列表来定义参数:

param queueNames array = [
  'queue1'
  'queue2'
]

然后使用循环定义队列资源,并将每个队列配置为将死信消息自动转发到另一个集中式队列:

resource queues 'Microsoft.ServiceBus/namespaces/queues@2018-01-01-preview' = [for queueName in queueNames: {
  parent: serviceBusNamespace
  name: queueName
  properties: {
    forwardDeadLetteredMessagesTo: deadLetterFirehoseQueueName
  }
}]

请参阅完整示例。

示例 3:多租户解决方案的资源

此示例演示如何在生成多租户解决方案时使用该模式。 Bicep 部署基于租户的逻辑列表创建复杂的资源集,并使用模块来简化共享资源和租户特定资源的创建。 每个租户都会在 Azure SQL 中获得自己的数据库,并在 Azure Front Door 中配置自己的自定义域。

此示例定义了一个指定租户列表的参数。 租户的定义只是租户标识符及其自定义域名:

param tenants array = [
  {
    id: 'fabrikam'
    domainName: 'fabrikam.com'
  }
  {
    id: 'contoso'
    domainName: 'contoso.com'
  }
]

主 Bicep 文件定义共享资源,然后使用模块循环遍历租户:

module tenantResources 'tenant-resources.bicep' = [for tenant in tenants: {
  name: 'tenant-${tenant.id}' 
  params: {
    location: location
    tenant: tenant
    sqlServerName: sqlServerName
    frontDoorProfileName: frontDoorProfileName
  }
}]

模块中已部署了特定于租户的资源。

请参阅完整示例。

注意事项

  • 开发或调试 Bicep 文件时,请考虑在不定义资源的情况下创建映射变量。 然后,使用变量的值定义输出,以便可以看到映射的结果。
  • 可以使用条件根据逻辑参数值选择性地部署资源。
  • 动态创建资源名称时,请确保名称满足部署的资源的要求。 可能需要为某些资源生成名称,而不是直接通过参数接受名称。

后续步骤

了解共享变量文件模式。