Azure 容器應用程式 允許你的應用程式安全地儲存敏感的設定值。 一旦祕密在應用程式層級定義,安全值即可供容器應用程式中的修訂版本使用。 此外,您還可以在級別規則內參考受保護的值。 如需有關將秘密用於 Dapr 的資訊,請參閱 Dapr 整合。
- 秘密的範圍定義在一個應用程式,排除應用程式的任何特定修訂。
- 新的修訂不會透過新增、移除或變更秘密來產生。
- 每個應用程式修訂版本都可以參考一或多個秘密。
- 多個修訂可以參考相同的機密。
更新或刪除的秘密不會自動影響您應用程式中現有的修訂。 當秘密更新或刪除時,您可以使用下列兩種方式之一回應變更:
- 新增修訂版本。
- 重新啟動現有的修訂版本。
在刪除秘密之前,請先部署不再參考舊密碼的新修訂版本。 然後停用參考秘密的所有修訂。
定義秘密
祕密定義為一組名稱/值組。 每個秘密的值會直接指定,或作為 Azure Key Vault 中儲存的秘密的參考。
在容器應用程式中儲存祕密值
以下內容用於透過入口網站或不同命令列選項定義秘密。
請進入你的容器應用程式,進入 Azure 入口網站。
在 安全性 區塊中,選擇 秘密。
選取新增。
在「新增祕密」窗格上,輸入下列資訊:
-
名稱:祕密名稱。
-
類型:選取「容器應用程式祕密」。
-
值:祕密的值。
選取新增。
秘密的定義位於 resources.properties.configuration.secrets 區段中的應用程式層級。
"resources": [
{
...
"properties": {
"configuration": {
"secrets": [
{
"name": "queue-connection-string",
"value": "<MY-CONNECTION-STRING-VALUE>"
}],
}
}
}
在這裡,佇列儲存帳號的連接字串會在 secrets 陣列中宣告。 在這個例子中,你會用你的連接字串值替換<MY-CONNECTION-STRING-VALUE>。
當您建立容器應用程式時,會使用 --secrets 參數來定義祕密。
- 此參數接受以空格分隔的名稱/值組集合。
- 等號 (
=) 會分隔每個配對。
az containerapp create \
--resource-group "my-resource-group" \
--name queuereader \
--environment "my-environment-name" \
--image demos/queuereader:v1 \
--secrets "queue-connection-string=<CONNECTION_STRING>"
此處會在 --secrets 參數中宣告佇列儲存體帳戶的連接字串。 請將<CONNECTION_STRING>替換為連線字串的值。
當您建立容器應用程式時,祕密會定義為一或多個透過 ConfigurationSecrets 參數傳送的祕密物件。
$EnvId = (Get-AzContainerAppManagedEnv -ResourceGroupName my-resource-group -EnvName my-environment-name).Id
$TemplateObj = New-AzContainerAppTemplateObject -Name queuereader -Image demos/queuereader:v1
$SecretObj = New-AzContainerAppSecretObject -Name queue-connection-string -Value $QueueConnectionString
$ContainerAppArgs = @{
Name = 'my-resource-group'
Location = '<location>'
ResourceGroupName = 'my-resource-group'
ManagedEnvironmentId = $EnvId
TemplateContainer = $TemplateObj
ConfigurationSecret = $SecretObj
}
New-AzContainerApp @ContainerAppArgs
這裡會宣告佇列儲存體帳戶的連接字串。
queue-connection-string 的值來自名為 $QueueConnectionString 的環境變數。
從 金鑰保存庫 參考秘密
當您設定一個秘密時,會建立一個連結至儲存在 Azure Key Vault 中的秘密。 容器應用程式會自動從 金鑰保存庫 取得秘密值,並將其作為秘密存在於你的容器應用程式中。
要參考 金鑰保存庫 的秘密,您必須先在您的容器應用程式中啟用管理身份,並授權該身份存取 金鑰保存庫 的秘密。
若在容器應用程式中啟用受控識別,請參閱受控識別。
若要授與 金鑰保存庫 秘密的存取權,請將 Azure RBAC 角色 金鑰保存庫 祕密使用者授與受控識別。
請進入你的容器應用程式,進入 Azure 入口網站。
在安全性區塊中,選擇「身份」。
在 系統指派 標籤頁中,將 狀態 設定為 開啟。
注意
您也可以使用使用者指派的受控識別,此身分識別可以跨多個資源重複使用,且與應用程式生命周期無關。 若要使用它,請選取 [使用者指派] 索引 標籤,然後選擇現有的身分識別。
選取 [ 儲存 ] 以啟用系統指派的受控識別。
彈出視窗確認您想啟用系統指派的管理身份,並以 Microsoft Entra ID 註冊您的容器應用程式。 選取 [是]。
在 安全性 區塊中,選擇 秘密。
選取新增。
在「新增祕密」窗格上,輸入下列資訊:
-
名稱:祕密名稱。
-
類型:選擇 金鑰保存庫 參考。
-
金鑰保存庫 秘密網址:你的秘密在 金鑰保存庫 中的 URI。 此 URI 格式如下:
https://<YOUR_KEY_VAULT_NAME>.vault.azure.net/secrets/<YOUR_SECRET_NAME>/<32_DIGIT_HEX_ID>
-
身份:選取系統指派。
選取新增。
秘密的定義位於 resources.properties.configuration.secrets 區段中的應用程式層級。
"resources": [
{
...
"properties": {
"configuration": {
"secrets": [
{
"name": "queue-connection-string",
"keyVaultUrl": "<KEY_VAULT_SECRET_URI>",
"identity": "system"
}],
}
}
}
在這裡,佇列儲存帳號的連接字串會在 secrets 陣列中宣告。 其值會自動從 金鑰保存庫 使用指定的身份識別取得。 若要使用使用者受控識別,請將 system 取代為身分識別的資源 ID。
請將 <KEY_VAULT_SECRET_URI> 替換為 金鑰保存庫 中您秘密的 URI。
當您建立容器應用程式時,會使用 --secrets 參數來定義祕密。
- 此參數接受以空格分隔的名稱/值組集合。
- 等號 (
=) 會分隔每個配對。
- 若要指定金鑰保存庫參考,請使用格式
<SECRET_NAME>=keyvaultref:<KEY_VAULT_SECRET_URI>,identityref:<MANAGED_IDENTITY_ID>。 例如,queue-connection-string=keyvaultref:https://mykeyvault.vault.azure.net/secrets/queuereader,identityref:/subscriptions/ffffffff-eeee-dddd-cccc-bbbbbbbbbbb0/resourcegroups/my-resource-group/providers/Microsoft.ManagedIdentity/userAssignedIdentities/my-identity。
az containerapp create \
--resource-group "my-resource-group" \
--name queuereader \
--environment "my-environment-name" \
--image demos/queuereader:v1 \
--user-assigned "<USER_ASSIGNED_IDENTITY_ID>" \
--secrets "queue-connection-string=keyvaultref:<KEY_VAULT_SECRET_URI>,identityref:<USER_ASSIGNED_IDENTITY_ID>"
此處會在 --secrets 參數中宣告佇列儲存體帳戶的連接字串。 請將 <KEY_VAULT_SECRET_URI> 替換為 金鑰保存庫 中您秘密的 URI。 將 <USER_ASSIGNED_IDENTITY_ID> 取代為使用者指派身分識別的資源 ID。
注意
使用者指定的身份必須有權限在 金鑰保存庫 中讀取該秘密。 系統指派的身分識別無法與建立命令搭配使用,因為建立容器應用程式之後才可使用。
PowerShell 不支援 Secrets 金鑰保存庫 的引用。
金鑰保存庫 祕密 URI 和祕密輪替
金鑰保存庫 的秘密 URI 必須採用以下格式之一:
-
https://myvault.vault.azure.net/secrets/mysecret/ec96f02080254f109c51a1f14cdb1931:參考密鑰的特定版本。
-
https://myvault.vault.azure.net/secrets/mysecret:參考祕密的最新版本。
若未在 URI 中指定版本,則應用程式會使用金鑰保存庫中的現有最新版本。 當較新版本可用時,應用程式會在 30 分鐘內自動擷取最新版本。 任何在環境變數中參考該祕密的作用中修訂版本,都會自動重新啟動以擷取新值。
若要完整控制使用哪一個祕密版本,請在 URI 中指定版本。
在環境變數中引用祕密
在應用程式層級宣告祕密之後 (如定義祕密一節中所述),您可以在容器應用程式中建立新的修訂時,於環境變數中參考這些祕密。 當環境變數參考秘密時,其值會以秘密中定義的值填入。
範例
以下範例展示了一個在應用程式層級宣告連接字串的應用程式。 此連線會在容器環境變數以及調整規則中被引用。
已在容器應用程式中定義祕密之後,便可在建立新的修訂時在環境變數中予以參考。
請進入你的容器應用程式,進入 Azure 入口網站。
在 [ 應用程式] 區段下,選取 [修訂和複本]。
在 [ 修訂和複本] 頁面中,選取 [ 建立新修訂]。
在 [建立及部署新的修訂] 頁面的 [容器] 標籤中,在 容器映像檔 區段下,選取一個容器。
選取編輯。
在 [ 編輯容器 內容] 窗格中,選取 [ 環境變數 ] 索引標籤。
選取新增。
輸入下列資訊:
-
名稱:環境變數的名稱。
-
來源:選取參考機密。
-
值:選取您先前定義的秘密。
選取儲存。
在 [ 建立及部署新的修訂 ] 頁面中,選取 [建立 ] 以建立新的修訂。
在此範例中,應用程式連接字串被宣告為 queue-connection-string,並在配置區塊的其他部分可用。
{
"$schema": "https://schema.management.azure.com/schemas/2019-08-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"location": {
"type": "String"
},
"environment_id": {
"type": "String"
},
"key_vault_secret_uri": { ⬅️
"type": "String" ⬅️
} ⬅️
},
"variables": {},
"resources": [
{
"name": "queuereader",
"type": "Microsoft.App/containerApps",
"apiVersion": "2022-03-01",
"kind": "containerapp",
"location": "[parameters('location')]",
"properties": {
"managedEnvironmentId": "[parameters('environment_id')]",
"configuration": {
"activeRevisionsMode": "single",
"secrets": [ ⬅️
{ ⬅️
"name": "queue-connection-string", ⬅️
"keyVaultUrl": "[parameters('key_vault_secret_uri')", ⬅️
"identity": "system" ⬅️
}] ⬅️
},
"template": {
"containers": [
{
"image": "myregistry/myQueueApp:v1",
"name": "myQueueApp",
"env": [
{
"name": "QueueName",
"value": "myqueue"
},
{
"name": "ConnectionString", ⬅️
"secretRef": "queue-connection-string" ⬅️
}
]
}
],
"scale": {
"minReplicas": 0,
"maxReplicas": 10,
"rules": [
{
"name": "myqueuerule",
"azureQueue": {
"queueName": "demoqueue",
"queueLength": 100,
"auth": [
{
"secretRef": "queue-connection-string", ⬅️
"triggerParameter": "connection" ⬅️
}
]
}
}
]
}
}
}
}]
}
在這裡,名為 connection-string 的環境變數會從應用層級 queue-connection-string 秘密取得其值。 此外,Azure 佇列儲存體 擴展規則的驗證設定會使用queue-connection-string 秘密以定義其連接。
若要避免在使用 ARM 範本時將秘密值提交至原始檔控制,請將秘密值作為 ARM 範本的參數傳遞。
在這個例子中,你用 Azure CLI 建立一個容器應用程式,並有一個在環境變數中被引用的秘密。 若要參考Azure CLI中環境變數中的秘密,將其值設為 secretref:,後接秘密名稱。
az containerapp create \
--resource-group "my-resource-group" \
--name myQueueApp \
--environment "my-environment-name" \
--image demos/myQueueApp:v1 \
--user-assigned "<USER_ASSIGNED_IDENTITY_ID>" \
--secrets "queue-connection-string=keyvaultref:<KEY_VAULT_SECRET_URI>,identityref:<USER_ASSIGNED_IDENTITY_ID>" \
--env-vars "QueueName=myqueue" "ConnectionString=secretref:queue-connection-string"
在這裡,名為 connection-string 的環境變數會從應用層級 queue-connection-string 秘密取得其值。
PowerShell 不支援 Secrets 金鑰保存庫 的引用。
在這個例子中,你用 Azure PowerShell 建立一個容器,並有一個在環境變數中引用的秘密。 若要在 PowerShell 中參考環境變數中的祕密,請將其值設定為 secretref:,後方接著祕密的名稱。
$EnvId = (Get-AzContainerAppManagedEnv -ResourceGroupName my-resource-group -EnvName my-environment-name).Id
$SecretObj = New-AzContainerAppSecretObject -Name queue-connection-string -Value $QueueConnectionString
$EnvVarObjQueue = New-AzContainerAppEnvironmentVarObject -Name QueueName -Value myqueue
$EnvVarObjConn = New-AzContainerAppEnvironmentVarObject -Name ConnectionString -SecretRef queue-connection-string -Value secretref
$TemplateObj = New-AzContainerAppTemplateObject -Name myQueueApp -Image demos/myQueueApp:v1 -Env $EnvVarObjQueue, $EnvVarObjConn
$ContainerAppArgs = @{
Name = 'myQueueApp'
Location = '<location>'
ResourceGroupName = 'my-resource-group'
ManagedEnvironmentId = $EnvId
TemplateContainer = $TemplateObj
ConfigurationSecret = $SecretObj
}
New-AzContainerApp @ContainerAppArgs
在這裡,名為 ConnectionString 的環境變數會從應用層級 $QueueConnectionString 秘密取得其值。
在磁碟區中掛接祕密
如 定義祕密一節所述,在應用程式層級宣告祕密之後,您可以在容器應用程式中建立新修訂版本時,於磁碟區掛接中參考這些祕密。 當您將敏感資訊掛接到一個卷中時,每個敏感資訊都會掛接為該卷中的一個檔案。 檔名是祕密的名稱,而檔案內容則是祕密值。 您可以在磁碟區掛接中載入所有祕密,也可以載入特定祕密。
範例
在容器應用程式中定義祕密後,可於建立新的修訂版本時在卷掛載中引用該祕密。
請進入你的容器應用程式,進入 Azure 入口網站。
在 [ 應用程式] 區段下,選取 [修訂和複本]。
在 [ 修訂和複本] 頁面中,選取 [ 建立新修訂]。
在 [建立及部署新的修訂] 頁面的 [容器] 標籤中,在 容器映像檔 區段下,選取一個容器。
選取編輯。
在 [編輯容器] 內容窗格中,選取 [磁碟區掛接] 索引標籤。
選取「建立新磁碟區」。
在 新增磁碟區 環境面板中,輸入下列資訊:
-
磁碟區類型:選取
Secret。
-
名稱:
mysecrets
-
掛載所有秘密資訊:已啟用
注意
如果您想要載入特定祕密,請停用掛接所有祕密,然後選取您想要載入的祕密。
選取新增。
在 [編輯容器內容] 窗格中的 [磁碟區名稱] 下,選取 mysecrets。
在掛接路徑底下,輸入 /mnt/secrets。
選取儲存。
在建立及部署新的修訂頁面中,選取 建立以建立具有磁碟區掛接的新修訂。
在此範例中,將會在應用程式等級宣告兩個祕密。 這些祕密會掛接在名為 mysecrets 類型的磁碟區 Secret 中。 磁碟區已掛接至路徑 /mnt/secrets。 應用程式之後即可在磁碟區掛接中參考這些祕密。
{
"$schema": "https://schema.management.azure.com/schemas/2019-08-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"location": {
"type": "String"
},
"environment_id": {
"type": "String"
},
"key_vault_secret_uri": {
"type": "Securestring"
},
"api-key": {
"type": "Securestring"
}
},
"variables": {},
"resources": [
{
"name": "queuereader",
"type": "Microsoft.App/containerApps",
"apiVersion": "2022-11-01-preview",
"kind": "containerapp",
"location": "[parameters('location')]",
"properties": {
"managedEnvironmentId": "[parameters('environment_id')]",
"configuration": {
"activeRevisionsMode": "single",
"secrets": [
{
"name": "queue-connection-string",
"keyVaultUrl": "[parameters('key_vault_secret_uri')",
"identity": "system"
},
{
"name": "api-key",
"value": "[parameters('api-key')]"
}
]
},
"template": {
"containers": [
{
"image": "myregistry/myQueueApp:v1",
"name": "myQueueApp",
"volumeMounts": [
{
"name": "mysecrets",
"mountPath": "/mnt/secrets"
}
]
}
],
"volumes": [
{
"name": "mysecrets",
"storageType": "Secret"
}
]
}
}
}]
}
若要載入特定祕密並在掛接的磁碟區內指定其路徑,您可以在磁碟區物件的 secrets 陣列中定義祕密。 下列範例示範如何使用 queue-connection-string 檔案名稱,只載入 mysecrets 磁碟區掛接中的 connection-string.txt 祕密。
{
"properties": {
...
"configuration": {
...
"secrets": [
{
"name": "queue-connection-string",
"keyVaultUrl": "[parameters('key_vault_secret_uri')",
"identity": "system"
},
{
"name": "api-key",
"value": "[parameters('api-key')]"
}
]
},
"template": {
"containers": [
{
"image": "myregistry/myQueueApp:v1",
"name": "myQueueApp",
"volumeMounts": [
{
"name": "mysecrets",
"mountPath": "/mnt/secrets"
}
]
}
],
"volumes": [
{
"name": "mysecrets",
"storageType": "Secret",
"secrets": [
{
"secretRef": "queue-connection-string",
"path": "connection-string.txt"
}
]
}
]
}
...
}
...
}
在您的應用程式中,您可以從位於 /mnt/secrets/connection-string.txt 的檔案讀取祕密。
在此範例中,將會在應用程式等級宣告兩個祕密。 這些祕密會掛接在名為 mysecrets 類型的磁碟區 Secret 中。 磁碟區已掛接至路徑 /mnt/secrets。 應用程式之後即可將這些祕密作為磁碟區掛接中的檔案來讀取。
az containerapp create \
--resource-group "my-resource-group" \
--name myQueueApp \
--environment "my-environment-name" \
--image demos/myQueueApp:v1 \
--user-assigned "<USER_ASSIGNED_IDENTITY_ID>" \
--secrets "queue-connection-string=keyvaultref:<KEY_VAULT_SECRET_URI>,identityref:<USER_ASSIGNED_IDENTITY_ID>" "api-key=$API_KEY" \
--secret-volume-mount "/mnt/secrets"
若要載入特定祕密,並在掛接的磁碟區內指定其路徑,請使用 YAML 定義您的應用程式。
疑難排解金鑰保管庫的引用
當你存取 Azure Key Vault 的機密資料時,可能會在擷取或同步過程中遇到問題。 以下是常見的錯誤與解決方法:
| 錯誤 |
原因 |
Resolution |
| 未啟用管理身份 |
容器應用程式沒有指派受管理身份。 |
在您的容器應用程式中啟用系統指派或使用者指派的管理身份。 請參閱<受控識別>(機器翻譯)。 |
| 身份未找到 |
指定的管理身份不存在,或是沒有指派給容器應用程式。 |
在 身份 區塊中確認身份是否已建立並指派到容器應用程式。 |
| 金鑰保存庫 中的機密被停用 |
該秘密在 金鑰保存庫 資源中被停用。 |
到你的 Azure Portal 裡的 金鑰保存庫 並啟用這個密鑰。 |
| 認證失敗 |
受管理身份缺乏讀取秘密所需的權限。 |
將金鑰保存庫機密使用者角色授予您的金鑰保存庫上的受控身份。 請參見 金鑰保存庫 Secrets User。 |
| RBAC 申請被拒 |
管理身份權限不足以存取 金鑰保存庫。 |
確認 金鑰保存庫 上的 RBAC 角色指派,並確保其中包含對機密的讀取權限。 |
下一步