练习 - 使用变量和输出循环

已完成

对于你所在的玩具公司,你需要在要推出小熊玩具的每个国家/地区部署虚拟网络。 开发人员还要求你为它们提供你已部署的每个区域 Azure SQL 逻辑服务器的完全限定的域名 (FQDN)。

在本练习中,你会将虚拟网络及其配置添加到 Bicep 代码中,并输出逻辑服务器的 FQDN。

在此过程中,你将:

  • 更新 Bicep 代码,为每个虚拟网络的子网指定一个参数。
  • 添加变量循环以创建子网数组,该数组将用于虚拟网络资源声明。
  • 添加输出循环以创建逻辑服务器 FQDN 的列表。
  • 部署 Bicep 文件,并验证部署。

将虚拟网络添加到 Bicep 文件

  1. 打开 main.bicep 文件。

  2. 在参数声明下,添加以下参数:

    @description('The IP address range for all virtual networks to use.')
    param virtualNetworkAddressPrefix string = '10.10.0.0/16'
    
    @description('The name and IP address range for each subnet in the virtual networks.')
    param subnets array = [
      {
        name: 'frontend'
        ipAddressRange: '10.10.5.0/24'
      }
      {
        name: 'backend'
        ipAddressRange: '10.10.10.0/24'
      }
    ]
    
  3. 在参数下面,添加一个空白行,然后添加 subnetProperties 变量循环:

    var subnetProperties = [for subnet in subnets: {
      name: subnet.name
      properties: {
        addressPrefix: subnet.ipAddressRange
      }
    }]
    
  4. 在文件底部的 databases 模块循环下面,添加以下资源循环:

    resource virtualNetworks 'Microsoft.Network/virtualNetworks@2024-01-01' = [for location in locations: {
      name: 'teddybear-${location}'
      location: location
      properties:{
        addressSpace:{
          addressPrefixes:[
            virtualNetworkAddressPrefix
          ]
        }
        subnets: subnetProperties
      }
    }]
    

    注意

    本示例针对所有虚拟网络使用相同的地址空间。 通常,当创建多个虚拟网络时,如果需要将它们连接在一起,则可能为其提供不同的地址空间。

  5. 保存对文件所做的更改。

将输出添加到数据库模块

  1. 打开 modules/database.bicep 文件。

  2. 在文件底部添加以下输出:

    output serverName string = sqlServer.name
    output location string = location
    output serverFullyQualifiedDomainName string = sqlServer.properties.fullyQualifiedDomainName
    
  3. 保存对文件所做的更改。

通过父 Bicep 文件流式传输输出

  1. 打开 main.bicep 文件。

  2. 在文件底部添加以下输出循环:

    output serverInfo array = [for i in range(0, length(locations)): {
      name: databases[i].outputs.serverName
      location: databases[i].outputs.location
      fullyQualifiedDomainName: databases[i].outputs.serverFullyQualifiedDomainName
    }]
    
  3. 保存对文件所做的更改。

验证 Bicep 文件

完成上述所有更改后,main.bicep 文件应如以下示例所示:

@description('The Azure regions into which the resources should be deployed.')
param locations array = [
  'westeurope'
  'eastus2'
  'eastasia'
]

@secure()
@description('The administrator login username for the SQL server.')
param sqlServerAdministratorLogin string

@secure()
@description('The administrator login password for the SQL server.')
param sqlServerAdministratorLoginPassword string

@description('The IP address range for all virtual networks to use.')
param virtualNetworkAddressPrefix string = '10.10.0.0/16'

@description('The name and IP address range for each subnet in the virtual networks.')
param subnets array = [
  {
    name: 'frontend'
    ipAddressRange: '10.10.5.0/24'
  }
  {
    name: 'backend'
    ipAddressRange: '10.10.10.0/24'
  }
]

var subnetProperties = [for subnet in subnets: {
  name: subnet.name
  properties: {
    addressPrefix: subnet.ipAddressRange
  }
}]

module databases 'modules/database.bicep' = [for location in locations: {
  name: 'database-${location}'
  params: {
    location: location
    sqlServerAdministratorLogin: sqlServerAdministratorLogin
    sqlServerAdministratorLoginPassword: sqlServerAdministratorLoginPassword
  }
}]

resource virtualNetworks 'Microsoft.Network/virtualNetworks@2024-01-01' = [for location in locations: {
  name: 'teddybear-${location}'
  location: location
  properties:{
    addressSpace:{
      addressPrefixes:[
        virtualNetworkAddressPrefix
      ]
    }
    subnets: subnetProperties
  }
}]

output serverInfo array = [for i in range(0, length(locations)): {
  name: databases[i].outputs.serverName
  location: databases[i].outputs.location
  fullyQualifiedDomainName: databases[i].outputs.serverFullyQualifiedDomainName
}]

database.bicep 文件应如以下示例所示:

@description('The Azure region into which the resources should be deployed.')
param location string

@secure()
@description('The administrator login username for the SQL server.')
param sqlServerAdministratorLogin string

@secure()
@description('The administrator login password for the SQL server.')
param sqlServerAdministratorLoginPassword string

@description('The name and tier of the SQL database SKU.')
param sqlDatabaseSku object = {
  name: 'Standard'
  tier: 'Standard'
}

@description('The name of the environment. This must be Development or Production.')
@allowed([
  'Development'
  'Production'
])
param environmentName string = 'Development'

@description('The name of the audit storage account SKU.')
param auditStorageAccountSkuName string = 'Standard_LRS'

var sqlServerName = 'teddy${location}${uniqueString(resourceGroup().id)}'
var sqlDatabaseName = 'TeddyBear'
var auditingEnabled = environmentName == 'Production'
var auditStorageAccountName = take('bearaudit${location}${uniqueString(resourceGroup().id)}', 24)

resource sqlServer 'Microsoft.Sql/servers@2023-08-01-preview' = {
  name: sqlServerName
  location: location
  properties: {
    administratorLogin: sqlServerAdministratorLogin
    administratorLoginPassword: sqlServerAdministratorLoginPassword
  }
}

resource sqlDatabase 'Microsoft.Sql/servers/databases@2023-08-01-preview' = {
  parent: sqlServer
  name: sqlDatabaseName
  location: location
  sku: sqlDatabaseSku
}

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

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

output serverName string = sqlServer.name
output location string = location
output serverFullyQualifiedDomainName string = sqlServer.properties.fullyQualifiedDomainName

如果不是,请复制示例或调整模板以与该示例一致。

将 Bicep 模板部署到 Azure

在 Visual Studio Code 终端中,运行以下代码以将 Bicep 模板部署到 Azure。 此过程可能需要几分钟才能完成,然后你会看到部署成功。

az deployment group create --template-file main.bicep

在 Visual Studio Code 终端中,运行以下 Azure PowerShell 命令,将 Bicep 模板部署到 Azure。 此过程可能需要几分钟才能完成,然后你会看到部署成功。

New-AzResourceGroupDeployment -TemplateFile main.bicep

注意

请务必使用与前面相同的登录名和密码,否则部署不会成功完成。

等待部署完成。

验证部署

部署完成后,需要验证是否部署了新的虚拟网络,以及是否按预期为它们配置了子网。

  1. 转到 Azure 门户,并确保你位于沙盒订阅中。

  2. 选择 沙盒资源组名称

  3. 验证虚拟网络是否已部署到三个 Azure 位置。

    Screenshot of the Azure portal, showing a list of virtual networks after deployment.

  4. 选择名为 teddybear-eastasia 的虚拟网络。

  5. 在搜索栏中,输入“子网”。 在“设置”下,选择“子网”。

    Screenshot of the Azure portal interface for the virtual network, showing the search field with Subnets entered.

  6. 验证已部署的子网是否具有 subnets 参数的默认值中指定的名称和 IP 地址。

    Screenshot of the Azure portal that shows two virtual network subnets after deployment.

  7. 检查部署命令的输出。 它应包括已部署的所有三个逻辑服务器的名称和 FQDN,如下所示:

    Screenshot of the deployment output, displaying the properties of the logical servers.

  1. 转到 Azure 门户,并确保你位于沙盒订阅中。

  2. 选择 沙盒资源组名称

  3. 验证虚拟网络是否已部署到三个 Azure 位置。

    Screenshot of the Azure portal, showing a list of virtual networks after deployment.

  4. 选择名为 teddybear-eastasia 的虚拟网络。

  5. 在搜索栏中,输入“子网”。 在“设置”下,选择“子网”。

    Screenshot of the Azure portal interface for the virtual network, showing the search field with Subnets entered.

  6. 验证已部署的子网是否具有 subnets 参数的默认值中指定的名称和 IP 地址。

    Screenshot of the Azure portal that shows two virtual network subnets after deployment.

  7. 检查部署命令的输出。 它应包括已部署的所有三个逻辑服务器的名称和 FQDN,如下所示:

    Screenshot of the deployment output, displaying the properties of the logical servers.