练习 - 添加参数文件和安全参数
在此练习中,你将创建一个参数文件,该文件为之前创建的 Bicep 文件提供值。 在同一参数文件中,还将添加 Azure Key Vault 引用来安全地提供敏感信息。
在此过程中,你将执行以下任务:
- 添加一些安全参数。
- 创建参数文件。
- 测试部署,确保参数文件有效。
- 创建密钥保管库和机密。
- 更新参数文件以引用密钥保管库机密。
- 重新测试部署,确保参数文件仍然有效。
删除应用服务计划 SKU 的默认值
若要使模板跨环境工作,Azure 应用服务计划的 SKU 详细信息将在参数文件中提供,而不是按默认值提供。
在 Visual Studio Code 的 main.bicep 文件中,更新 appServicePlanSku
参数以删除其默认值。
@description('The name and tier of the App Service plan SKU.')
param appServicePlanSku object
添加新参数
现在,需要添加 SQL Server 和数据库。 首先,为管理员登录名和密码以及数据库 SKU 添加参数。 稍后将设置其值。
在 Visual Studio Code 的 main.bicep 文件中,在当前参数声明下面添加 sqlServerAdministratorLogin
、sqlServerAdministratorPassword
和 sqlDatabaseSku
参数。 完成时,你的参数声明应如以下示例所示:
@description('The name of the environment. This must be dev, test, or prod.')
@allowed([
'dev'
'test'
'prod'
])
param environmentName string = 'dev'
@description('The unique name of the solution. This is used to ensure that resource names are unique.')
@minLength(5)
@maxLength(30)
param solutionName string = 'toyhr${uniqueString(resourceGroup().id)}'
@description('The number of App Service plan instances.')
@minValue(1)
@maxValue(10)
param appServicePlanInstanceCount int = 1
@description('The name and tier of the App Service plan SKU.')
param appServicePlanSku object
@description('The Azure region into which the resources should be deployed.')
param location string = 'eastus'
@secure()
@description('The administrator login username for the SQL server.')
param sqlServerAdministratorLogin string
@secure()
@description('The administrator login password for the SQL server.')
param sqlServerAdministratorPassword string
@description('The name and tier of the SQL database SKU.')
param sqlDatabaseSku object
请注意,没有为 sqlServerAdministratorLogin
和 sqlServerAdministratorPassword
参数指定默认值。 为安全参数添加默认值是一种错误的安全做法。 此外,没有为 sqlDatabaseSku
指定默认值。 你将在参数文件中指定一个值。
添加新变量
在 Visual Studio Code 的 main.bicep 文件中,将 sqlServerName
和 sqlDatabaseName
变量添加到现有变量下面。 完成时,你的变量声明应如以下示例所示:
var appServicePlanName = '${environmentName}-${solutionName}-plan'
var appServiceAppName = '${environmentName}-${solutionName}-app'
var sqlServerName = '${environmentName}-${solutionName}-sql'
var sqlDatabaseName = 'Employees'
添加 SQL Server 和数据库资源
在 Visual Studio Code 的 main.bicep 文件中,将以下代码添加到文件底部:
resource sqlServer 'Microsoft.Sql/servers@2023-08-01-preview' = { name: sqlServerName location: location properties: { administratorLogin: sqlServerAdministratorLogin administratorLoginPassword: sqlServerAdministratorPassword } } resource sqlDatabase 'Microsoft.Sql/servers/databases@2023-08-01-preview' = { parent: sqlServer name: sqlDatabaseName location: location sku: { name: sqlDatabaseSku.name tier: sqlDatabaseSku.tier } }
保存对文件所做的更改。
验证 Bicep 文件
完成上述所有更改后,Bicep 文件应如以下示例所示:
@description('The name of the environment. This must be dev, test, or prod.')
@allowed([
'dev'
'test'
'prod'
])
param environmentName string = 'dev'
@description('The unique name of the solution. This is used to ensure that resource names are unique.')
@minLength(5)
@maxLength(30)
param solutionName string = 'toyhr${uniqueString(resourceGroup().id)}'
@description('The number of App Service plan instances.')
@minValue(1)
@maxValue(10)
param appServicePlanInstanceCount int = 1
@description('The name and tier of the App Service plan SKU.')
param appServicePlanSku object
@description('The Azure region into which the resources should be deployed.')
param location string = 'eastus'
@secure()
@description('The administrator login username for the SQL server.')
param sqlServerAdministratorLogin string
@secure()
@description('The administrator login password for the SQL server.')
param sqlServerAdministratorPassword string
@description('The name and tier of the SQL database SKU.')
param sqlDatabaseSku object
var appServicePlanName = '${environmentName}-${solutionName}-plan'
var appServiceAppName = '${environmentName}-${solutionName}-app'
var sqlServerName = '${environmentName}-${solutionName}-sql'
var sqlDatabaseName = 'Employees'
resource appServicePlan 'Microsoft.Web/serverfarms@2023-12-01' = {
name: appServicePlanName
location: location
sku: {
name: appServicePlanSku.name
tier: appServicePlanSku.tier
capacity: appServicePlanInstanceCount
}
}
resource appServiceApp 'Microsoft.Web/sites@2023-12-01' = {
name: appServiceAppName
location: location
properties: {
serverFarmId: appServicePlan.id
httpsOnly: true
}
}
resource sqlServer 'Microsoft.Sql/servers@2023-08-01-preview' = {
name: sqlServerName
location: location
properties: {
administratorLogin: sqlServerAdministratorLogin
administratorLoginPassword: sqlServerAdministratorPassword
}
}
resource sqlDatabase 'Microsoft.Sql/servers/databases@2023-08-01-preview' = {
parent: sqlServer
name: sqlDatabaseName
location: location
sku: {
name: sqlDatabaseSku.name
tier: sqlDatabaseSku.tier
}
}
如果不是,请复制示例或调整模板以与该示例一致。
创建参数文件
打开 Visual Studio Code,然后打开 main.bicep 文件所在的文件夹。 在同一文件夹中,创建名为 main.parameters.dev.json 的新文件。
在 main.parameters.dev.json 文件中,添加以下代码:
{ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#", "contentVersion": "1.0.0.0", "parameters": { "appServicePlanSku": { "value": { "name": "F1", "tier": "Free" } }, "sqlDatabaseSku": { "value": { "name": "Standard", "tier": "Standard" } } } }
保存对文件所做的更改。
使用参数文件部署 Bicep 模板
在终端中运行以下 Azure CLI 命令。 请注意,你要为部署提供参数文件。
az deployment group create \
--template-file main.bicep \
--parameters main.parameters.dev.json
在终端中运行以下 Azure PowerShell 命令。 请注意,你要为部署提供参数文件。
New-AzResourceGroupDeployment `
-TemplateFile main.bicep `
-TemplateParameterFile main.parameters.dev.json
执行部署时,系统会提示输入 sqlServerAdministratorLogin
和 sqlServerAdministratorPassword
参数的值。 无需指定 solutionName
,因为它在模板中指定了默认值。 无需指定其他参数值,因为它们的值在参数文件中指定。
提示
当你输入安全参数时,选择的值必须遵循以下规则:
sqlServerAdministratorLogin
不能是容易猜到的登录名,如admin
或root
。 名称只能包含字母数字字符,并且必须以字母开头。sqlServerAdministratorPassword
必须至少为 8 个字符,并且包含小写字母、大写字母、数字和符号。 有关密码复杂性的详细信息,请参阅 SQL Azure 密码策略。
如果参数值不满足要求,Azure SQL 将不会部署服务器。
此外,请确保记下输入的登录名和密码。 下一部分你将用到它们。
部署可能需要几分钟时间才能完成。
创建密钥保管库和机密
玩具公司已有一个密钥保管库,该保管库具有部署所需的机密。 若要模拟此场景,需要创建新的密钥保管库并添加一些要使用的机密。
在终端中,执行以下命令以创建密钥保管库和机密。 执行这些命令之前,请更新变量值。 密钥保管库名称必须是 3 到 24 个字符的全局唯一字符串,只能包含大写字母和小写字母、连字符 (-
) 和数字。 例如 demo-kv-1234567abcdefg。
注意
请确保使用在上一步骤中使用的相同登录名和密码。 如果没有,下一个部署将不会成功完成。
对于 keyVaultName
,请将 YOUR-KEY-VAULT-NAME
替换为密钥保管库的名称。 login
和 password
变量的 read
命令将提示你输入值。 键入时,这些值不会显示在终端中,也不会保存在命令历史记录中。
若要保护 Bash 终端会话中的变量值,请注意以下各项:
- 变量值不存储为安全字符串,可以通过输入命令(如在命令行上输入
$yourVariableName
或使用echo
命令)来进行显示。 在本练习中,在创建保管库机密后,可以在不输入值的情况下通过运行read
命令而来删除每个变量的现有值。 az keyvault secret set
使用--value
参数创建机密的值。 命令的输出显示名为value
的属性,其中包含机密的值。 可以使用--output none
参数禁止显示命令的整个输出,如示例所示。
若要创建 keyVaultName
、login
和 password
变量,请单独运行每个命令。 然后,可以运行命令块来创建密钥保管库和机密。
keyVaultName='YOUR-KEY-VAULT-NAME'
read -s -p "Enter the login name: " login
read -s -p "Enter the password: " password
az keyvault create --name $keyVaultName --location eastus --enabled-for-template-deployment true
az keyvault secret set --vault-name $keyVaultName --name "sqlServerAdministratorLogin" --value $login --output none
az keyvault secret set --vault-name $keyVaultName --name "sqlServerAdministratorPassword" --value $password --output none
备注
在保管库上设置 --enabled-for-template-deployment
设置,以便 Azure 可以在部署期间使用保管库中的机密。 如果未设置此设置,则默认情况下,部署无法访问保管库中的机密。
此外,执行部署的用户还必须具有访问保管库的权限。 由于你创建了密钥保管库,因此你是所有者,在本练习中不需要显式授予权限。 对于自己的保管库,需要授予对机密的访问权限。
对于 keyVaultName
,请将 YOUR-KEY-VAULT-NAME
替换为密钥保管库的名称。 login
和 password
变量的 Read-Host
命令将提示你输入值。 键入时,这些值不会显示在终端中,也不会保存在命令历史记录中。 将值以安全字符串的形式存储。
若要创建 keyVaultName
、login
和 password
变量,请单独运行每个命令。 然后,可以运行命令块来创建密钥保管库和机密。
$keyVaultName = 'YOUR-KEY-VAULT-NAME'
$login = Read-Host "Enter the login name" -AsSecureString
$password = Read-Host "Enter the password" -AsSecureString
New-AzKeyVault -VaultName $keyVaultName -Location eastus -EnabledForTemplateDeployment
Set-AzKeyVaultSecret -VaultName $keyVaultName -Name 'sqlServerAdministratorLogin' -SecretValue $login
Set-AzKeyVaultSecret -VaultName $keyVaultName -Name 'sqlServerAdministratorPassword' -SecretValue $password
备注
在保管库上设置 -EnabledForTemplateDeployment
设置,以便 Azure 可以在部署期间使用保管库中的机密。 如果未设置此设置,则默认情况下,部署无法访问保管库中的机密。
此外,执行部署的用户还必须具有访问保管库的权限。 由于你创建了密钥保管库,因此你是所有者,在本练习中不需要显式授予权限。 对于自己的保管库,需要授予对机密的访问权限。
获取密钥保管库的资源 ID
若要在部署中使用密钥保管库机密,需要保管库的资源 ID。 运行以下命令以检索密钥保管库的资源 ID:
az keyvault show --name $keyVaultName --query id --output tsv
(Get-AzKeyVault -Name $keyVaultName).ResourceId
资源 ID 将如以下示例所示:
/subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e/resourceGroups/PlatformResources/providers/Microsoft.KeyVault/vaults/toysecrets
复制资源 ID。 在下一步骤中将使用它。
向参数文件添加密钥保管库引用
在 main.parameters.dev.json 文件中,在
sqlDatabaseSku
参数的右大括号后面追加以下代码。 请确保将YOUR-KEY-VAULT-RESOURCE-ID
替换为在上一步中复制的密钥保管库资源 ID 的值。 完成后,参数文件应如以下示例所示:{ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#", "contentVersion": "1.0.0.0", "parameters": { "appServicePlanSku": { "value": { "name": "F1", "tier": "Free" } }, "sqlDatabaseSku": { "value": { "name": "Standard", "tier": "Standard" } }, "sqlServerAdministratorLogin": { "reference": { "keyVault": { "id": "YOUR-KEY-VAULT-RESOURCE-ID" }, "secretName": "sqlServerAdministratorLogin" } }, "sqlServerAdministratorPassword": { "reference": { "keyVault": { "id": "YOUR-KEY-VAULT-RESOURCE-ID" }, "secretName": "sqlServerAdministratorPassword" } } } }
保存对文件所做的更改。
使用参数文件和 Azure Key Vault 引用部署 Bicep 模板
在终端中运行以下 Azure CLI 命令。 你要提供参数文件以及 Bicep 文件。
az deployment group create \
--template-file main.bicep \
--parameters main.parameters.dev.json
在终端中运行以下 Azure PowerShell 命令。 你要提供参数文件以及 Bicep 文件。
New-AzResourceGroupDeployment `
-TemplateFile main.bicep `
-TemplateParameterFile main.parameters.dev.json
本次执行部署时,系统会提示输入 sqlServerAdministratorLogin
和 sqlServerAdministratorPassword
参数的值。 Azure 改为从密钥保管库中检索值。
由于 Azure 资源已存在,因此本次部署会更快完成。
检查你的部署
在浏览器中返回到 Azure 门户。 转到你的资源组。 你仍然会看到一个成功的部署,因为部署使用了与第一个部署相同的名称。
选择“1 个成功”链接。
选择名为“main”的部署。
在左侧菜单中,选择“输入”。
请注意,
appServicePlanSku
和sqlDatabaseSku
参数值都设置为参数文件中的值。 另请注意,sqlServerAdministratorLogin
和sqlServerAdministratorPassword
参数值不会显示,因为已对它们应用@secure()
修饰器。