使用 Bicep 來管理秘密
部署通常需要在您的 Azure 環境中安全地儲存和傳播祕密。 Bicep 和 Azure 提供許多功能,可協助您管理部署中的秘密。
盡可能避免秘密
在許多情況下,可以避免完全使用秘密。 許多 Azure 資源可讓受控識別 進行驗證並獲得授權,以存取 Azure 內的其他資源,而不需要處理或管理任何認證。 此外,某些 Azure 服務可以為您自動產生 HTTPS 憑證,讓您無法處理憑證和私鑰。 盡可能使用受控識別和服務管理憑證。
使用安全參數
在您需要提供秘密給 Bicep 部署做為參數時,請使用@secure()
裝飾項目。 當您將參數標示為安全時,Azure Resource Manager 會避免記錄值,或在 Azure 入口網站、Azure CLI 或 Azure PowerShell 中顯示該值。
避免秘密輸出
請勿將 Bicep 輸出用於安全資料。 輸出會記錄至部署歷程記錄,而任何可存取部署的人都可以檢視部署輸出的值。
如果您需要在 Bicep 部署內產生秘密,並將其提供給呼叫者或其他資源使用,請考慮下列其中一種方法。
動態查詢秘密
有時候,您需要從某個資源存取秘密,以設定另一個資源。 例如,您可能已在另一個部署中建立記憶體帳戶,而且需要存取其主鍵來設定 Azure Functions 應用程式。 您可以使用 existing
關鍵詞來取得預先建立之記憶體帳戶的強型別參考,然後使用記憶體帳戶的 listKeys()
方法來建立具有主鍵的 連接字串。
下列範例是較大範例的一部分。 如需您可以部署的 Bicep 檔案,請參閱完整檔案。
param location string = resourceGroup().location
param storageAccountName string
param functionAppName string = 'fn-${uniqueString(resourceGroup().id)}'
var appServicePlanName = 'MyPlan'
var applicationInsightsName = 'MyApplicationInsights'
resource storageAccount 'Microsoft.Storage/storageAccounts@2021-06-01' existing = {
name: storageAccountName
}
var storageAccountConnectionString = 'DefaultEndpointsProtocol=https;AccountName=${storageAccount.name};EndpointSuffix=${environment().suffixes.storage};AccountKey=${listKeys(storageAccount.id, storageAccount.apiVersion).keys[0].value}'
resource functionApp 'Microsoft.Web/sites@2023-12-01' = {
name: functionAppName
location: location
kind: 'functionapp'
properties: {
httpsOnly: true
serverFarmId: appServicePlan.id
siteConfig: {
appSettings: [
{
name: 'APPINSIGHTS_INSTRUMENTATIONKEY'
value: applicationInsights.properties.InstrumentationKey
}
{
name: 'AzureWebJobsStorage'
value: storageAccountConnectionString
}
{
name: 'FUNCTIONS_EXTENSION_VERSION'
value: '~3'
}
{
name: 'FUNCTIONS_WORKER_RUNTIME'
value: 'dotnet'
}
{
name: 'WEBSITE_CONTENTAZUREFILECONNECTIONSTRING'
value: storageAccountConnectionString
}
]
}
}
}
resource appServicePlan 'Microsoft.Web/serverfarms@2023-12-01' = {
name: appServicePlanName
location: location
sku: {
name: 'Y1'
tier: 'Dynamic'
}
}
resource applicationInsights 'Microsoft.Insights/components@2020-02-02' = {
name: applicationInsightsName
location: location
kind: 'web'
properties: {
Application_Type: 'web'
publicNetworkAccessForIngestion: 'Enabled'
publicNetworkAccessForQuery: 'Enabled'
}
}
採用這種方法可協助您避免將秘密傳入或傳出 Bicep 檔案,以及將秘密儲存在密鑰保存庫中。
使用 Key Vault
Azure Key Vault 是專為儲存和管理安全資料而設計。 使用金鑰保存庫來管理您的秘密、憑證、金鑰,以及其他需要保護和共用的資料。
您可以使用 Bicep 來建立和管理保存庫和秘密。 透過建立型別 Microsoft.KeyVault/vaults
的資源來定義您的保存庫。
建立保存庫時,您必須決定可以存取其中資料的使用者和項目。 如果您打算從 Bicep 檔案讀取保存庫的秘密,請將 enabledForTemplateDeployment
屬性設定為 true
。
將秘密新增至金鑰保存庫
秘密是子資源,而且可以使用型別 Microsoft.KeyVault/vaults/secrets
來建立。 下列範例示範如何建立保存庫和秘密。
下列範例是較大範例的一部分。 如需您可以部署的 Bicep 檔案,請參閱完整檔案。
param location string = resourceGroup().location
param keyVaultName string = 'mykv${uniqueString(resourceGroup().id)}'
resource keyVault 'Microsoft.KeyVault/vaults@2023-07-01' = {
name: keyVaultName
location: location
properties: {
enabledForTemplateDeployment: true
tenantId: tenant().tenantId
accessPolicies: [
]
sku: {
name: 'standard'
family: 'A'
}
}
}
resource keyVaultSecret 'Microsoft.KeyVault/vaults/secrets@2023-07-01' = {
parent: keyVault
name: 'MySecretName'
properties: {
value: 'MyVerySecretValue'
}
}
提示
使用自動化部署管線時,有時可能會很難判斷如何針對您的部署啟動金鑰保存庫秘密。 例如,如果您已取得 API 金鑰以用於與外部 API 通訊,就必須先將秘密新增至保存庫,才能在您的部署中使用。
當您使用來自第三方的密碼時,您可能需要手動將它們新增至保存庫,才能參考所有後續用途的秘密。
透過模組使用金鑰保存庫
採用 Bicep 模組時,您可以使用getSecret
函式來提供安全參數。
您也可以同時使用 existing
和 scope
關鍵字,來參照另一個資源群組所定義的金鑰保存庫。 在下列範例中,Bicep 檔案是部署至名為「網路」的資源群組。 模組參數 mySecret 的值定義於名為 contosonworkingsecrets 的密鑰保存庫中,其位於 Secrets 資源群組中:
resource networkingSecretsKeyVault 'Microsoft.KeyVault/vaults@2023-07-01' existing = {
scope: resourceGroup('Secrets')
name: 'contosonetworkingsecrets'
}
module exampleModule 'module.bicep' = {
name: 'exampleModule'
params: {
mySecret: networkingSecretsKeyVault.getSecret('mySecret')
}
}
在 .bicepparam 檔案中使用金鑰保存庫
當您使用 .bicepparam
檔案格式時,您可以使用 getSecret
函式為參數提供安全值。
提供訂用帳戶標識碼、資源組名和金鑰保存庫名稱,以參考密鑰保存庫。 您可以藉由提供秘密名稱來取得秘密的值。 您可以選擇性地提供秘密版本;如果您不這麼做,則會使用最新版本。
using './main.bicep'
param secureUserName = az.getSecret('<subscriptionId>', '<resourceGroupName>', '<keyVaultName>', '<secretName>', '<secretVersion>')
param securePassword = az.getSecret('<subscriptionId>', '<resourceGroupName>', '<keyVaultName>', '<secretName>')
在管線中使用秘密
當您使用管線來部署 Azure 資源時,下列最佳做法可協助您謹慎處理秘密:
- 請避免將秘密儲存在您的程式碼存放庫中。 例如,請勿將秘密新增至參數檔案或管線定義 YAML 檔案。
- 在 GitHub Actions 中,請使用加密的秘密來儲存安全資料。 使用秘密掃描來偵測任何意外認可的祕密。
- 在 Azure Pipelines 中,使用秘密變數來儲存安全資料。
相關資源
- 資源檔案:
- Azure 功能:
- Bicep 功能:
- 快速入門範本:
- Azure Pipelines:
- GitHub Actions: