Azure Container Apps でシークレットを管理する
[アーティクル] 05/24/2023
11 人の共同作成者
フィードバック
この記事の内容
Azure Container Apps を使うと、アプリケーションで機密性の高い構成値を安全に格納できます。 シークレットがアプリケーション レベルで定義されると、コンテナー アプリのリビジョンにセキュリティで保護された値を使用できるようになります。 さらに、スケール ルール内でセキュリティで保護された値を参照できます。 Dapr でシークレットを使用する方法の詳細については、Dapr 統合 に関するページを参照してください。
シークレットのスコープはアプリケーションであり、アプリケーションの特定のリビジョンの外部です。
シークレットを追加、削除、または変更しても、新しいリビジョンは生成されません。
アプリケーションの各リビジョンで、1 つまたは複数のシークレットを参照できます。
複数のリビジョンで同じシークレットを参照できます。
シークレットを更新または削除しても、アプリ内の既存のリビジョンには自動的には影響しません。 シークレットが更新または削除されるときは、2 つの方法のいずれかで変更に対応できます。
新しいリビジョンをデプロイします。
既存のリビジョンを再起動します。
シークレットを削除する前に、古いシークレットを参照しない新しいリビジョンをデプロイします。 次に、シークレットを参照するすべてのリビジョンを非アクティブ化します。
シークレットの定義
シークレットは、名前と値のペアのセットとして定義されます。 各シークレットの値は、直接指定するか、Azure Key Vault に格納されているシークレットへの参照として指定します。
Container Apps にシークレット値を格納する
ポータルを介して、またはさまざまなコマンド ライン オプションを介してシークレットを定義する場合。
Azure portal でコンテナー アプリに移動します。
[設定] セクションで、[シークレット] を選択します。
[追加] を選択します。
[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 を有効にし、ID に Key Vault シークレットへのアクセス権を付与する必要があります。
コンテナー アプリでマネージド ID を有効にするには、マネージド ID に関する記事を参照してください。
Key Vault シークレットへのアクセス権を付与するには、Key Vault で作成したマネージド ID のアクセス ポリシーを作成 します。 このポリシーで "Get" シークレット アクセス許可を有効にします。
Azure portal でコンテナー アプリに移動します。
[設定] セクションで、[ID] を選択します。
[システム割り当て済み] タブで [オン] を選びます。
[保存] を選んでシステム割り当てマネージド ID を有効にします。
[設定] セクションで、[シークレット] を選択します。
[追加] を選択します。
[Add secret] (シークレットの追加) コンテキスト ペインに次の情報を入力します。
名前 : シークレットの名前。
種類 : [キー コンテナー参照] を選びます。
Key Vault secret URL (Key Vault シークレットの URL) : Key Vault のシークレットの URI。
ID : Key Vault からシークレットを取得するために使う 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 の場合、リソース ID ではなく system
を使います。
Note
ユーザー割り当て ID は、Key Vault のシークレットを読み取るアクセス権を持っている必要があります。 システム割り当て ID は、コンテナー アプリの作成後に使用できるようになるので、create コマンドでは使用できません。
シークレット Key Vault の参照は PowerShell ではサポートされていません。
Key Vault シークレットの URI とシークレットのローテーション
Key Vault シークレットの URI は次の形式のいずれかにする必要があります。
https://myvault.vault.azure.net/secrets/mysecret/ec96f02080254f109c51a1f14cdb1931
: 特定バージョンのシークレットを参照します。
https://myvault.vault.azure.net/secrets/mysecret
: シークレットの最新バージョンを参照します。
URI にバージョンが指定されていない場合、アプリはキー コンテナーに存在する最新バージョンを使います。 新しいバージョンが使用可能になると、30 分以内にアプリは最新バージョンを自動的に取得します。 環境変数でシークレットを参照するアクティブなリビジョンは自動的に再起動され、新しい値が取得されます。
使うシークレットのバージョンを完全に制御するには、URI でバージョンを指定します。
環境変数でのシークレットの参照
「シークレットの定義 」セクションの説明に従いアプリケーション レベルでシークレットを宣言した後、コンテナー アプリで新しいリビジョンを作成するとき、環境変数でそれらのシークレットを参照できます。 環境変数でシークレットを参照すると、その値には、シークレットで定義されている値が設定されます。
例
次の例は、アプリケーション レベルで接続文字列を宣言するアプリケーションを示しています。 この接続は、コンテナー環境変数とスケール ルールで参照されています。
コンテナー アプリでシークレットを定義 したら、新しいリビジョンを作成するときに環境変数でそれを参照できます。
Azure portal でコンテナー アプリに移動します。
[Revision management] (リビジョン管理) ページを開きます。
[新しいリビジョンの作成] を選択します。
[新しいリビジョンの作成とデプロイ] ページでコンテナーを選びます。
[環境変数] セクションで [追加] を選びます。
次の情報を入力してください。
名前 : 環境変数の名前。
ソース : [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"
},
"queue-connection-string": {
"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",
"value": "[parameters('queue-connection-string')]"
}]
},
"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 \
--secrets "queue-connection-string=$CONNECTIONSTRING" \
--env-vars "QueueName=myqueue" "ConnectionString=secretref:queue-connection-string"
ここで、connection-string
という名前の環境変数の値は、アプリケーション レベルの queue-connection-string
シークレットから取得されます。
この例では、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 portal でコンテナー アプリに移動します。
[Revision management] (リビジョン管理) ページを開きます。
[新しいリビジョンの作成] を選択します。
[Create and deploy new revision] (新しいリビジョンの作成とデプロイ) ページで。
コンテナーを選び、[編集] を選びます。
[ボリュームのマウント] セクションで [シークレット] セクションを展開します。
[Create new volume] (新しいボリュームの作成) を選びます。
次の情報を入力してください。
名前 : mysecrets
Mount all secrets (すべてのシークレットをマウントする) : 有効
Note
特定のシークレットを読み込む場合は、[Mount all secrets] (すべてのシークレットをマウントする) を無効にして、読み込むシークレットを選びます。
[追加] を選択します。
[ボリューム名] で [mysecrets] を選びます。
[マウント パス] に「/mnt/secrets 」と入力します。
[保存] を選択します。
[作成] を選び、ボリューム マウントを使って新しいリビジョンを作成します。
この例では、アプリケーション レベルで 2 つのシークレットを宣言します。 これらのシークレットは、種類 Secret
の mysecrets
というボリュームにマウントされます。 このボリュームはパス /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"
},
"queue-connection-string": {
"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",
"value": "[parameters('queue-connection-string')]"
},
{
"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
配列でシークレットを定義します。 次の例は、connection-string.txt
というファイル名で mysecrets
ボリューム マウントの queue-connection-string
シークレットのみを読み込む方法を示しています。
{
"properties": {
...
"configuration": {
...
"secrets": [
{
"name": "queue-connection-string",
"value": "[parameters('queue-connection-string')]"
},
{
"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 つのシークレットを宣言します。 これらのシークレットは、種類 Secret
の mysecrets
というボリュームにマウントされます。 このボリュームはパス /mnt/secrets
にマウントされます。 これで、アプリケーションはボリューム マウントのファイルとしてシークレットを読み取ることができるようになります。
az containerapp create \
--resource-group "my-resource-group" \
--name myQueueApp \
--environment "my-environment-name" \
--image demos/myQueueApp:v1 \
--secrets "queue-connection-string=$CONNECTIONSTRING" "api-key=$API_KEY" \
--secret-volume-mount "/mnt/secrets"
特定のシークレットを読み込んでマウントされたボリューム内のパスを指定するには、YAML を使ってアプリを定義します。
シークレットをボリュームとしてマウントすることは、PowerShell ではサポートされていません。
次のステップ