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

已完成

对于你所在的玩具公司,你需要在要推出小熊玩具的每个国家/地区部署虚拟网络。 开发人员还要求你为它们提供你已部署的每个区域 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 位置。

    Azure 门户的屏幕截图,其中显示了部署后的虚拟网络列表。

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

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

    Azure 门户中虚拟网络界面的屏幕截图,其中显示了输入了“子网”的搜索字段。

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

    Azure 门户的屏幕截图,其中显示了部署后的两个虚拟网络子网。

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

    部署输出的屏幕截图,其中显示了逻辑服务器的属性。

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

  2. 选择 沙盒资源组名称

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

    Azure 门户的屏幕截图,其中显示了部署后的虚拟网络列表。

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

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

    Azure 门户中虚拟网络界面的屏幕截图,其中显示了输入了“子网”的搜索字段。

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

    Azure 门户的屏幕截图,其中显示了部署后的两个虚拟网络子网。

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

    部署输出的屏幕截图,其中显示了逻辑服务器的属性。