Azure Container Appsを使用すると、アプリケーションは機密性の高い構成値を安全に格納できます。 シークレットがアプリケーション レベルで定義されると、コンテナー アプリのリビジョンにセキュリティで保護された値を使用できるようになります。 さらに、スケール ルール内でセキュリティで保護された値を参照できます。 Dapr でシークレットを使用する方法の詳細については、Dapr 統合に関するページを参照してください。
- シークレットはアプリケーション全体に関するものであり、特定のアプリケーションのリビジョンには依存しません。
- シークレットを追加、削除、または変更しても、新しいリビジョンは生成されません。
- アプリケーションの各リビジョンで、1 つまたは複数のシークレットを参照できます。
- 複数のリビジョンで同じシークレットを参照できます。
シークレットを更新または削除しても、アプリ内の既存のリビジョンには自動的には影響しません。 シークレットが更新または削除されるときは、2 つの方法のいずれかで変更に対応できます。
- 新しいリビジョンをデプロイします。
- 既存のリビジョンを再起動します。
シークレットを削除する前に、古いシークレットを参照しない新しいリビジョンをデプロイします。 次に、シークレットを参照するすべてのリビジョンを非アクティブ化します。
シークレットの定義
シークレットは、名前と値のペアのセットとして定義されます。 各シークレットの値は、Azure Key Vaultに格納されているシークレットへの直接または参照として指定されます。
Container Apps にシークレット値を格納する
以下は、ポータルまたは異なるコマンド ライン オプションを使用してシークレットを定義する場合に使用されます。
Azure ポータルでコンテナー アプリに移動します。
[ セキュリティ ] セクションで、[ シークレット] を選択します。
[追加] を選択します。
[Add secret] (シークレットの追加) コンテキスト ペインに次の情報を入力します。
-
名前: シークレットの名前。
-
種類: Container Apps シークレットを選びます。
-
値: シークレットの値。
[追加] を選択します。
シークレットは、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 パラメーター経由で渡される 1 つ以上のシークレット オブジェクトとしてシークレットが定義されます。
$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 という名前の環境変数から取得されます。
Key Vaultからシークレットを参照する
シークレットを定義するときは、Azure Key Vaultに格納されているシークレットへの参照を作成します。 Container Apps は、Key Vaultからシークレット値を自動的に取得し、コンテナー アプリでシークレットとして使用できるようにします。
Key Vaultからシークレットを参照するには、まずコンテナー アプリでマネージド ID を有効にし、Key Vault シークレットへのアクセス権を ID に付与する必要があります。
コンテナー アプリでマネージド ID を有効にするには、マネージド ID に関する記事を参照してください。
Key Vault シークレットへのアクセスを許可するには、マネージド ID に Azure RBAC ロール Key Vault シークレット ユーザーを付与します。
Azure ポータルでコンテナー アプリに移動します。
[ セキュリティ ] セクションで、[ ID] を選択します。
[システム割り当て済み] タブで、[状態] を [オン] に設定します。
注
また、ユーザー割り当てマネージド ID を使用することもできます。これは、複数のリソース間で再利用でき、アプリのライフサイクルとは別に保持されます。 これを使用するには、[ ユーザー割り当て ] タブを選択し、既存の ID を選択します。
[保存] を選択してシステム割り当てマネージド ID を有効にします。
システム割り当てマネージド ID を有効にし、コンテナー アプリをMicrosoft Entra IDに登録することを確認するポップアップが表示されます。
[はい] を選択します。
[ セキュリティ ] セクションで、[ シークレット] を選択します。
[追加] を選択します。
[Add secret] (シークレットの追加) コンテキスト ペインに次の情報を入力します。
-
名前: シークレットの名前。
-
Type: Key Vault参照を選択します。
-
Key Vault シークレット URL: Key Vault内のシークレットの URI。 この URI の形式は次のとおりです:
https://<YOUR_KEY_VAULT_NAME>.vault.azure.net/secrets/<YOUR_SECRET_NAME>/<32_DIGIT_HEX_ID>
-
ID: [システム割り当て] を選択します。
[追加] を選択します。
シークレットは、resources.properties.configuration.secrets セクションのアプリケーション レベルで定義されます。
"resources": [
{
...
"properties": {
"configuration": {
"secrets": [
{
"name": "queue-connection-string",
"keyVaultUrl": "<KEY_VAULT_SECRET_URI>",
"identity": "system"
}],
}
}
}
ここでは、キュー ストレージ アカウントへの接続文字列は、secrets 配列で宣言されています。 その値は、指定した ID を使用してKey Vaultから自動的に取得されます。 ユーザー マネージド ID を使うには、system を ID のリソース ID に置き換えます。
<KEY_VAULT_SECRET_URI> を、Key Vault内のシークレットの URI に置き換えます。
コンテナー アプリを作成するとき、--secrets パラメーターを使用してシークレットを定義します。
- このパラメーターには、スペースで区切った一連の名前と値のペアを指定します。
- 等号 (
=) は、各ペアを区切ります。
- Key Vault参照を指定するには、
<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> を、Key Vault内のシークレットの URI に置き換えます。
<USER_ASSIGNED_IDENTITY_ID> をユーザー割り当て ID のリソース ID に置き換えます。
注
ユーザー割り当て ID には、Key Vault内のシークレットを読み取るアクセス権が必要です。 システム割り当て ID は、コンテナー アプリの作成後に使用できるようになるので、create コマンドでは使用できません。
シークレットKey Vault参照は、PowerShell ではサポートされていません。
注
UDR With Azure Firewall を使用している場合は、AzureKeyVault サービス タグと login.microsoft.com FQDN をファイアウォールの許可リストに追加する必要があります。 必要な追加のサービス タグを決定するには、Azure Firewallを参照してください。
シークレット URI とシークレットローテーションのKey Vault
Key Vault シークレット URI は、次のいずれかの形式にする必要があります。
-
https://myvault.vault.azure.net/secrets/mysecret/ec96f02080254f109c51a1f14cdb1931: 特定バージョンのシークレットを参照します。
-
https://myvault.vault.azure.net/secrets/mysecret: シークレットの最新バージョンを参照します。
URI にバージョンが指定されていない場合、アプリはキー コンテナーに存在する最新バージョンを使います。 新しいバージョンが使用可能になると、30 分以内にアプリは最新バージョンを自動的に取得します。 環境変数でシークレットを参照するアクティブなリビジョンは自動的に再起動され、新しい値が取得されます。
使うシークレットのバージョンを完全に制御するには、URI でバージョンを指定します。
環境変数でのシークレットの参照
「シークレットの定義」セクションの説明に従いアプリケーション レベルでシークレットを宣言した後、コンテナー アプリで新しいリビジョンを作成するとき、環境変数でそれらのシークレットを参照できます。 環境変数でシークレットを参照すると、その値には、シークレットで定義されている値が設定されます。
例
次の例は、アプリケーション レベルで接続文字列を宣言するアプリケーションを示しています。 この接続は、コンテナー環境変数とスケール ルールで参照されています。
コンテナー アプリでシークレットを定義したら、新しいリビジョンを作成するときに環境変数でそれを参照できます。
Azure ポータルでコンテナー アプリに移動します。
[アプリケーション] セクションで、[リビジョンとレプリカ] を選択します。
リビジョンとレプリカ ページで、[新しいリビジョンの作成] を選択します。
新しいリビジョンの作成とデプロイ ページの [コンテナー] タブの [コンテナー イメージ] セクションで、コンテナーを選択します。
編集を選択します。
[コンテナーの編集] コンテキスト ウィンドウで、[環境変数] タブを選択します。
[追加] を選択します。
次の情報を入力してください。
-
名前: 環境変数の名前。
-
ソース: [Reference a secret] (シークレットの参照) を選びます。
-
値: 前に定義したシークレットを選択します。
[保存] を選択します。
新しいリビジョンの作成とデプロイ ページで、[作成] を選択して新しいリビジョンを作成します。
この例では、アプリケーション 接続文字列は 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 Storage スケール ルールの認証構成では、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 シークレットから取得されます。
シークレットKey Vault参照は、PowerShell ではサポートされていません。
この例では、環境変数で参照されるシークレットと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 ポータルでコンテナー アプリに移動します。
[アプリケーション] セクションで、[リビジョンとレプリカ] を選択します。
リビジョンとレプリカ ページで、[新しいリビジョンの作成] を選択します。
新しいリビジョンの作成とデプロイ ページの [コンテナー] タブの [コンテナー イメージ] セクションで、コンテナーを選択します。
編集を選択します。
[コンテナーの編集] コンテキスト ペインで、[ボリューム マウント] タブを選びます。
[Create new volume] (新しいボリュームの作成) を選びます。
[ボリュームの追加] コンテキスト ウィンドウで、次の情報を入力します:
-
ボリュームの種類:
Secret を選択します。
-
名前:
mysecrets
-
Mount all secrets (すべてのシークレットをマウントする): 有効
注
特定のシークレットを読み込む場合は、[Mount all secrets] (すべてのシークレットをマウントする) を無効にして、読み込むシークレットを選びます。
[追加] を選択します。
[コンテナーの編集] コンテキスト ウィンドウの [ボリューム名] で、mysecrets を選択します。
[マウント パス] に「/mnt/secrets」と入力します。
[保存] を選択します。
新しいリビジョンの作成とデプロイ ページで、[作成] を選択し、ボリューム マウントを使用して新しいリビジョンを作成します。
この例では、アプリケーション レベルで 2 つのシークレットを宣言します。 これらのシークレットは、種類 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 にあるファイルからシークレットを読み取ることができます。
この例では、アプリケーション レベルで 2 つのシークレットを宣言します。 これらのシークレットは、種類 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 を使ってアプリを定義します。
PowerShell では、シークレットをボリュームとしてマウントすることはサポートされていません。
Key Vault リファレンスのトラブルシューティング
Azure Key Vaultからシークレットを参照すると、シークレットの取得または同期中に問題が発生する可能性があります。 一般的なエラーと解決策を次に示します。
| エラー |
原因 |
Resolution |
| 管理IDが有効になっていません |
コンテナー アプリにはマネージド ID が割り当てられません。 |
コンテナー アプリでシステム割り当てマネージド ID またはユーザー割り当てマネージド ID を有効にします。
マネージド ID に関するページを参照してください。 |
| ID が見つかりません |
指定したマネージド ID が存在しないか、コンテナー アプリに割り当てられません。 |
ID が作成 され、[ID] セクションでコンテナー アプリに割り当てられているかどうかを確認します。 |
| Key Vaultでシークレットが無効になっている |
シークレットは、Key Vault リソースで無効になっています。 |
Azure ポータルでKey Vaultに移動し、シークレットを有効にします。 |
| 認証に失敗しました |
マネージド ID には、シークレットを読み取るために必要なアクセス許可がありません。 |
Key Vaultのマネージド ID に Key Vault シークレット ユーザー ロールを付与します。 「Key Vault シークレット ユーザーを参照してください。 |
| RBAC アクセス許可が拒否されました |
マネージド ID には、Key Vaultにアクセスするための十分なアクセス許可がありません。 |
Key Vaultの RBAC ロールの割り当てを確認し、シークレットの読み取りアクセス許可が含まれていることを確認します。 |
次のステップ