練習 - 新增參數檔案與安全參數

已完成

在此練習中,您將建立參數檔案,以提供您先前所建立 Bicep 檔案的值。 在相同的參數檔案中,您也會新增 Azure Key Vault 參考,以安全地提供敏感性資訊。

在此過程期間,您將執行下列工作:

  • 新增一些安全參數。
  • 建立參數檔案。
  • 測試部署,以確定參數檔案有效。
  • 建立金鑰保存庫與祕密。
  • 更新參數檔案,以參考金鑰保存庫祕密。
  • 重新測試部署,以確定參數檔案仍然有效。

移除 App Service 方案 SKU 的預設值

為讓您的範本可以在環境中運作,參數檔案中會提供 Azure App Service 方案 SKU 詳細資料,而不是預設值。

在 Visual Studio Code 的 main.bicep 檔案中,更新 appServicePlanSku 參數,以移除其預設值。

@description('The name and tier of the App Service plan SKU.')
param appServicePlanSku object

新增參數

現在您需要新增 SQL 伺服器與資料庫。 首先,您將新增系統管理員登入與密碼的參數,以及資料庫 SKU。 您稍後會設定其值。

在 Visual Studio Code 的 main.bicep 檔案中,於目前的參數宣告下,新增 sqlServerAdministratorLoginsqlServerAdministratorPasswordsqlDatabaseSku 參數。 當您完成時,您的參數宣告應類似於下列範例所示:

@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

請注意,您不會指定 sqlServerAdministratorLoginsqlServerAdministratorPassword 參數的預設值。 為安全參數新增預設值,是極不安全的做法。 此外,您也不會指定 sqlDatabaseSku 的預設值。 您將在參數檔案中指定值。

新增變數

在 Visual Studio Code 的 main.bicep 檔案中,於現有的變數下,新增 sqlServerNamesqlDatabaseName 變數。 當您完成時,您的變數宣告應類似於下列範例所示:

var appServicePlanName = '${environmentName}-${solutionName}-plan'
var appServiceAppName = '${environmentName}-${solutionName}-app'
var sqlServerName = '${environmentName}-${solutionName}-sql'
var sqlDatabaseName = 'Employees'

新增 SQL 伺服器與資料庫資源

  1. 在 Visual Studio Code 的 main.bicep 檔案中,於檔案底部新增下列程式碼:

    resource sqlServer 'Microsoft.Sql/servers@2022-05-01-preview' = {
      name: sqlServerName
      location: location
      properties: {
        administratorLogin: sqlServerAdministratorLogin
        administratorLoginPassword: sqlServerAdministratorPassword
      }
    }
    
    resource sqlDatabase 'Microsoft.Sql/servers/databases@2022-05-01-preview' = {
      parent: sqlServer
      name: sqlDatabaseName
      location: location
      sku: {
        name: sqlDatabaseSku.name
        tier: sqlDatabaseSku.tier
      }
    }
    
  2. 儲存對檔案所做的變更。

驗證 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@2022-03-01' = {
  name: appServicePlanName
  location: location
  sku: {
    name: appServicePlanSku.name
    tier: appServicePlanSku.tier
    capacity: appServicePlanInstanceCount
  }
}

resource appServiceApp 'Microsoft.Web/sites@2022-03-01' = {
  name: appServiceAppName
  location: location
  properties: {
    serverFarmId: appServicePlan.id
    httpsOnly: true
  }
}

resource sqlServer 'Microsoft.Sql/servers@2022-05-01-preview' = {
  name: sqlServerName
  location: location
  properties: {
    administratorLogin: sqlServerAdministratorLogin
    administratorLoginPassword: sqlServerAdministratorPassword
  }
}

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

否則,請複製範例或調整範本,以符合範例。

建立參數檔案

  1. 開啟 Visual Studio Code,然後開啟 main.bicep 檔案所在的資料夾。 在相同的資料夾中,建立名為 main.parameters.dev.json 的新檔案。

  2. 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"
          }
        }
      }
    }
    
  3. 儲存對檔案所做的變更。

使用參數檔案部署 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

執行部署時,會提示您輸入 sqlServerAdministratorLoginsqlServerAdministratorPassword 參數的值。 因為範本中已有指定 solutionName 的預設值,所以您不需要加以指定。 因為其他參數的值會在參數檔案中指定,所以您不需要加以指定。

提示

輸入安全參數時,您選擇的值必須符合下列規則:

  • 避免為 sqlServerAdministratorLogin 指定容易猜到的登入名稱,例如 adminroot。 只能包含英數字元,且開頭必須是字母。
  • sqlServerAdministratorPassword 的長度必須至少為 8 個字元,且必須包含小寫字母、大寫字母、數字及符號。 如需密碼複雜性的詳細資訊,請參閱 SQL Azure 密碼原則

若參數值不符合需求,Azure SQL 將不會部署伺服器。

此外,「請務必記下您輸入的登入與密碼」。 您將在下一節中用到。

部署可能需要幾分鐘的時間才能完成。

建立金鑰保存庫與祕密

您的玩具公司已經有一個金鑰保存庫,包含了其部署所需的祕密。 若要模擬此案例,您將建立新的金鑰保存庫,並新增一些要使用的祕密。

在終端機中執行下列命令,以建立金鑰保存庫與祕密。 執行這些命令之前,請先更新變數值。 金鑰保存庫名稱必須是 3 到 24 個字元的全域唯一字串,只能包含大寫和小寫字母、連字號 (-) 和數字。 例如,demo-kv-1234567abcdefg

警告

請確定您使用的登入與密碼,與上一個步驟中使用的相同。 若不同,下一個部署將無法順利完成。

針對 keyVaultName,將 YOUR-KEY-VAULT-NAME 取代為您的金鑰保存庫的名稱。 loginpassword 變數的 read 命令會提示您輸入值。 輸入時這些值不會顯示在終端中,也不會儲存在您的命令歷程記錄中。

若要保護 Bash 終端工作階段中的變數值,請注意下列項目:

  • 變數值不會儲存為安全字串,而且可以透過在命令列輸入 $yourVariableName 之類的命令或使用 echo 命令來顯示。 在此練習中,建立保存庫祕密之後,您可以執行 read 命令而不輸入值來移除每個變數的現有值。
  • az keyvault secret set 會使用 --value 參數來建立祕密的值。 命令的輸出會顯示名為 value 的屬性,其中包含祕密的值。 您可以使用參數 --output none 來隱藏命令的整個輸出,如範例所示。

若要建立 keyVaultNameloginpassword 變數,請個別執行每個命令。 然後,您可以執行命令區塊來建立金鑰保存庫和祕密。

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 取代為您的金鑰保存庫的名稱。 loginpassword 變數的 Read-Host 命令會提示您輸入值。 輸入時這些值不會顯示在終端中,也不會儲存在您的命令歷程記錄中。 值會儲存為安全字串。

若要建立 keyVaultNameloginpassword 變數,請個別執行每個命令。 然後,您可以執行命令區塊來建立金鑰保存庫和祕密。

$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 可以在部署期間,使用保存庫中的祕密。 若您未設定此設定,則根據預設,您的部署將無法存取保存庫中的祕密。

此外,執行部署的人員也必須擁有存取保存庫的權限。 因為您已建立金鑰保存庫 (您是擁有者),所以不需要在此練習中明確地授與權限。 針對您自己的保存庫,您需要授與祕密的存取權

取得金鑰保存庫的資源識別碼

若要在您的部署中使用金鑰保存庫祕密,則需要保存庫的資源識別碼。 執行下列命令,以擷取金鑰保存庫的資源識別碼:

az keyvault show --name $keyVaultName --query id --output tsv
(Get-AzKeyVault -Name $keyVaultName).ResourceId

資源識別碼看起來將如下列範例所示:

/subscriptions/f0750bbe-ea75-4ae5-b24d-a92ca601da2c/resourceGroups/PlatformResources/providers/Microsoft.KeyVault/vaults/toysecrets

複製資源識別碼。 您將在下一個步驟中使用它。

將金鑰保存庫參考新增至參數檔案

  1. main.parameters.dev.json 檔案中,在 sqlDatabaseSku 參數的右括號之後附加下列程式碼。 請務必以您在上一個步驟中所複製金鑰保存庫資源識別碼的值取代 YOUR-KEY-VAULT-RESOURCE-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"
          }
        }
      }
    }
    
  2. 儲存對檔案所做的變更。

使用參數檔案與 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

這次會在執行部署時,提示您輸入 sqlServerAdministratorLoginsqlServerAdministratorPassword 參數的值。 Azure 會改為從您的金鑰保存庫擷取值。

因為 Azure 資源已經存在,所以這次部署會更快速地完成。

檢查您的部署

  1. 在瀏覽器中,返回 Azure 入口網站。 移至您的資源群組。 您仍會看到一個成功的部署,因為此部署使用的名稱與第一個部署相同。

  2. 選取 [1 個成功] 連結。

  3. 選取名為 main 的部署。

  4. 從左側功能表中選取 [輸入]

  5. 請注意,appServicePlanSkusqlDatabaseSku 參數值都已設定為參數檔案中的值。 此外也請注意 sqlServerAdministratorLoginsqlServerAdministratorPassword 參數值不會顯示,因為您已將 @secure() 裝飾項目套用至這些值。

    Screenshot of the Azure portal interface for the specific deployment showing the parameter values.