练习 - 按条件部署资源

已完成

注意

首次激活沙盒并接受这些条款后,你的 Microsoft 帐户将与名为“Microsoft Learn 沙盒”的新 Azure 目录相关联。 还会将你添加到名为“Concierge 订阅”的特殊订阅中。

你需要将你的玩具公司的资源部署到各种环境,并且你想要使用参数和条件来控制部署到每个环境的内容。

在本练习中,你将创建一个 Azure SQL 逻辑服务器和数据库。 然后,你将添加审核设置以确保启用审核,但你只想要在部署到生产环境时启用它。 为了启用审核,你需要有一个存储帐户,并且也只在将资源部署到生产环境时部署它。

在此过程中,你将:

  • 创建一个 Bicep 文件,用于定义具有数据库的逻辑服务器。
  • 添加一个存储帐户和 SQL 审核设置,其中每个设置都是使用条件部署的。
  • 为开发环境设置一个基础结构,然后验证结果。
  • 针对生产环境重新部署基础结构,然后查看更改。

本练习使用适用于 Visual Studio Code 的 Bicep 扩展。 请务必在 Visual Studio Code 中安装此扩展。

使用逻辑服务器和数据库创建 Bicep 模板

  1. 打开 Visual Studio Code。

  2. 新建一个名为 main.bicep 的文件。

  3. 保存空文件,以便 Visual Studio Code 加载 Bicep 工具。

    你可以选择“文件”>“另存为”,也可以在 Windows 中选择Ctrl+S(在 macOS 上选择 ⌘+S)。 请务必记住保存文件的位置。 例如,你需要创建一个“模板”文件夹来将其存储在其中。

  4. 若要定义逻辑服务器和数据库,请向文件添加以下内容,并添加这些资源所需的参数和变量。 自行输入内容,而不是复制和粘贴,这样就可以了解工具如何帮助你编写 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'
    }
    
    var sqlServerName = 'teddy${location}${uniqueString(resourceGroup().id)}'
    var sqlDatabaseName = 'TeddyBear'
    
    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
    }
    

    请注意,所有参数都包括 @description 修饰器,方便你轻松使用。 另请注意,sqlServerAdministratorLoginsqlServerAdministratorLoginPassword 参数都应用了 @secure 修饰器。 这会让 Bicep 知道,这些参数值是敏感的。 Azure 不会将敏感值打印到日志中。

添加存储帐户

在逻辑服务器的审核设置中,需要指定一个存储帐户来包含审核数据。 你将更新 Bicep 文件以创建此存储帐户,但前提是将会启用审核。

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

    @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'
    
  2. 在变量声明下,添加以下变量:

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

    请注意,你将创建一个名为 auditingEnabled 的变量,该变量将用作部署审核资源的条件。 在创建这种变量时,可以使 Bicep 代码更清晰易读。 查看资源条件的任何人都可以明确地了解代码。

    另请注意,auditStorageAccountName 变量使用名为 take() 的函数。 存储帐户名称的最大长度为 24 个字符,因此此函数会截掉字符串的末尾以确保名称有效。

  3. 在文件底部的资源下,为存储帐户添加以下资源定义:

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

    请注意,存储帐户的定义包括 if 关键字,用于指定部署条件。

添加审核设置

  1. 在刚刚添加的存储帐户资源下面,添加以下代码:

    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 : ''
      }
    }
    

    请注意,定义包含与存储帐户相同的 if 条件。 此外,storageEndpointstorageAccountAccessKey 属性使用问号 (?) 三元运算符,以确保其值始终有效。 如果不这样做,Azure 资源管理器会先计算表达式的值,然后再计算资源部署条件并返回错误,因为找不到存储帐户。

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

验证 Bicep 文件

完成上述所有更改后,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 : ''
  }
}

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

将 Bicep 模板部署到 Azure

若要将此模板部署到 Azure,你需要从 Visual Studio Code 终端登录到 Azure 帐户。 请确保安装了 Azure CLI,并记得使用你用于激活沙盒的同一帐户登录。

  1. 在“终端”菜单中,选择“新终端”。 终端窗口通常在屏幕的下半部分打开。

  2. 如果终端窗口右侧显示的 shell 为“bash”,则将打开正确的 shell,你可以跳到下一部分。

    Visual Studio Code 终端窗口的屏幕截图,其中显示了 bash 选项。

  3. 如果出现“bash”以外的 shell,请选择 shell 下拉箭头,然后选择“Azure Cloud Shell (Bash)”

    Visual Studio Code 终端窗口的屏幕截图,其中显示了终端 shell 下拉列表并选中了“Git Bash (默认)”。

  4. 在终端 shell 列表中,选择“bash”。

    Visual Studio Code 终端窗口的屏幕截图,其中选中了 bash 终端。

  5. 在终端中,转到保存模板的目录。 例如,如果将模板保存到 templates 文件夹,则可以使用以下命令:

    cd templates
    

安装 Bicep

运行以下命令以确保具有最新版本的 Bicep:

az bicep install && az bicep upgrade

登录 Azure

  1. 在 Visual Studio Code 终端中,运行以下命令登录到 Azure:

    az login
    
  2. 在打开的浏览器中,登录到 Azure 帐户。

    Visual Studio Code 终端显示与此帐户关联的订阅列表。

  3. 为在此会话中运行的所有 Azure CLI 命令设置默认订阅。

    az account set --subscription "Concierge Subscription"
    

    注意

    如果最近使用了多个沙盒,终端可能会显示多个 Concierge 订阅实例。 在这种情况下,请使用下面的两个步骤来设置一个默认订阅。 如果前面的命令成功,且仅列出一个 Concierge 订阅,则跳过下面的两个步骤。

  4. 获取 Concierge 订阅 ID。

     az account list \
       --refresh \
       --query "[?contains(name, 'Concierge Subscription')].id" \
       --output table
    
  5. 使用订阅 ID 设置默认订阅。 将 {your subscription ID} 替换为最新的 Concierge 订阅 ID。

    az account set --subscription {your subscription ID}
    

设置默认资源组

当你使用 Azure CLI 时,可以设置默认资源组,并忽略本练习中其他 Azure CLI 命令的参数。 将默认值设置为在沙盒环境中为你创建的资源组。

az configure --defaults group="<rgn>[sandbox resource group name]</rgn>"

使用 Azure CLI 将模板部署到 Azure

在 Visual Studio Code 终端中,运行以下代码以将 Bicep 模板部署到 Azure。 请注意,你要将 location 参数显式设置为 westus3

az deployment group create --template-file main.bicep --parameters location=westus3

若要将此模板部署到 Azure,需要从 Visual Studio Code 终端登录到 Azure 帐户。 请确保已安装 Azure PowerShell,并且登录的帐户与激活了沙盒的帐户相同。

  1. 在“终端”菜单中,选择“新终端”。 终端窗口通常在屏幕的下半部分打开。

  2. 如果终端窗口右侧显示的 shell 为“powershell”或“pwsh”,则会打开正确的 shell,你可以跳到下一部分。

    Visual Studio Code 终端窗口的屏幕截图,其中在 shell 下拉列表中显示了 pwsh 选项。

  3. 如果出现“powershell”或“pwsh”以外的 shell,请选择 shell 下拉箭头,然后选择“PowerShell”

    Visual Studio Code 终端窗口的屏幕截图,其中显示了终端 shell 下拉列表并选中了 PowerShell。

  4. 在终端 shell 列表中,选择“powershell”或“pwsh”。

    Visual Studio Code 终端窗口的屏幕截图,其中选择了 PowerShell 终端。

  5. 在终端中,转到保存模板的目录。 例如,如果将模板保存到 templates 文件夹,则可以使用以下命令:

    Set-Location -Path templates
    

安装 Bicep CLI

若要从 Azure PowerShell 中使用 Bicep,请安装 Bicep CLI

使用 Azure PowerShell 登录到 Azure

  1. 在 Visual Studio Code 终端中,运行以下命令:

    Connect-AzAccount
    

    在打开的浏览器中,登录到 Azure 帐户。

  2. 登录到 Azure 后,终端会显示与此帐户关联的订阅列表。

    如果已激活沙盒,则会显示名为“Concierge 订阅”的订阅。 请在本练习的其余部分使用此订阅。

  3. 为在此会话中运行的所有 Azure PowerShell 命令设置默认订阅。

    $context = Get-AzSubscription -SubscriptionName 'Concierge Subscription'
    Set-AzContext $context
    

    注意

    如果最近使用了多个沙盒,终端可能会显示多个 Concierge 订阅实例。 在这种情况下,请使用下面的两个步骤来设置一个默认订阅。 如果前面的命令成功,且仅列出一个 Concierge 订阅,则跳过下面的两个步骤。

  4. 获取订阅 ID。 运行以下命令将列出你的订阅及其 ID。 查看 Concierge Subscription,然后复制第二列中的 ID。 它类似于 aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e

    Get-AzSubscription
    
  5. 将处于活动状态的订阅更改为“Concierge 订阅”。 请务必将 {Your subscription ID} 替换为复制的内容。

    $context = Get-AzSubscription -SubscriptionId {Your subscription ID}
    Set-AzContext $context
    

设置默认资源组

你可以设置默认资源组,并忽略本练习中其他 Azure PowerShell 命令的参数。 将此默认值设置为在沙盒环境中为你创建的资源组。

Set-AzDefault -ResourceGroupName <rgn>[sandbox resource group name]</rgn>

使用 Azure PowerShell 将模板部署到 Azure

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

New-AzResourceGroupDeployment -TemplateFile main.bicep -location westus3

执行部署时,系统会提示输入 sqlServerAdministratorLoginsqlServerAdministratorLoginPassword 参数的值。

提示

当你输入安全参数时,选择的值必须遵循特定规则:

  • sqlServerAdministratorLogin 不能是容易猜到的登录名,例如 adminroot。 名称只能包含字母数字字符,并且必须以字母开头。
  • sqlServerAdministratorLoginPassword 必须至少为 8 个字符,并且包含小写字母、大写字母、数字和符号。 有关密码复杂性的详细信息,请参阅 SQL Azure 密码策略

如果参数值不满足要求,Azure SQL 将不会部署逻辑服务器。

此外,请务必记下你输入的登录名和密码。 稍后将再次用到它们。

由于尚未为 environmentName 参数指定值,因此使用默认值 Development

等待部署完成。 如果部署失败并显示一条消息,指出某个位置不接受创建新的 Windows Azure SQL 数据库服务器,请选择其他区域,例如 eastuseastus2

验证部署

使用 Azure 门户检查部署的资源,并检查每个部署的结果。

  1. 转到 Azure 门户,通过以下操作确保你位于沙盒订阅中:

    a. 选择右上角的头像。
    b. 选择“切换目录”。 在列表中,选择“Microsoft Learn 沙盒”目录。

  2. 在左窗格中,选择“资源组”。

  3. 选择 沙盒资源组名称

  4. 在“概述”部分中,你会看到一个成功的部署。 还可以看到已部署逻辑服务器和 SQL 数据库,但用于审核的存储帐户没有部署。

    注意

    名称以 cloudshell 开头的存储帐户与部署无关,是由 Learn 沙盒创建的。

    Azure 门户资源组“概述”窗格的屏幕截图,其中一个部分显示成功的部署。

  5. 在“部署”旁边,选择“1 已成功”以查看部署详细信息。

    Azure 门户资源组“概述”窗格的屏幕截图,其中显示成功部署的更多详细信息。

  6. 选择名为“main”的部署,查看部署了哪些资源,然后选择“部署详细信息”以将其展开。

    在这种情况下,会部署一个逻辑服务器和一个 SQL 数据库。 请注意,存储帐户和审核设置不在资源列表中。

    Azure 门户资源组中针对特定部署的“概述”窗格的屏幕截图,其中列出了一个逻辑服务器和数据库资源。

  7. 使页面在浏览器中处于打开状态。 稍后会再次检查部署。

为生产环境重新部署

上一个部署中使用了 environmentName 参数的默认值,这意味着它被设置为 Development

现在将参数值显式设置为 Production。 通过进行此更改,预期将部署用于审核的存储帐户,并且将在逻辑服务器上启用审核。

为生产环境部署模板

在 Visual Studio Code 终端中,运行以下代码,将 Bicep 模板部署到 Azure:

az deployment group create --template-file main.bicep --parameters environmentName=Production location=westus3

在 Visual Studio Code 终端中,运行以下 Azure PowerShell 命令,将模板部署到 Azure:

New-AzResourceGroupDeployment -TemplateFile main.bicep -environmentName Production -location westus3

注意

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

一两分钟后,部署应会成功完成。

验证重新部署

要完成本练习,请验证重新部署是否已成功完成,以及是否已启用审核。

  1. 返回 Azure 门户,转到资源组。 如果你已打开资源组,请选择“刷新”。

    你应该会看到一个用于审核的额外的存储帐户已部署。

    Azure 门户资源组“概述”窗格的屏幕截图,其中显示了已部署用于审核的存储帐户。

  2. 选择逻辑服务器(查找类型为“SQL 服务器”的资源)。

  3. 在搜索字段中,输入“审核”。 选择“安全性”下的“审核”。

    Azure 门户中逻辑服务器界面的屏幕截图,其中显示了输入了“审核”的搜索字段。

  4. 验证是否为此逻辑服务器启用了审核。

    Azure 门户中逻辑服务器界面的屏幕截图,其中显示了已启用审核配置。