Bicep デプロイ時に Azure Key Vault を使用して、セキュリティで保護されたパラメーター値を渡す

お使いの Bicep ファイルやパラメーター ファイルにセキュリティで保護された値 (パスワードなど) を直接入れる代わりに、デプロイ時に、Azure Key Vault から値を取得できます。 モジュールsecure:true 修飾子を持つ string パラメーターを必要とする場合は、getSecret 関数を使用してキー コンテナーのシークレットを取得できます。 参照するのは Key Vault ID だけであるため、値が公開されることはありません。

重要

この記事では、機密の値をテンプレート パラメーターとして渡す方法に焦点を当てます。 シークレットがパラメーターとして渡されるとき、キー コンテナーは別のサブスクリプションに存在するか、デプロイ先のリソース グループに存在することがあります。

この記事では、仮想マシンのプロパティを、キー コンテナー内の証明書の URL に設定する方法については説明しません。 そのシナリオのクイックスタート テンプレートについては、Azure Key Vault から証明書を仮想マシンにインストールする方法に関する記事を参照してください。

キー コンテナーとシークレットをデプロイする

Bicep のデプロイ時にキー コンテナーにアクセスするには、キー コンテナーの enabledForTemplateDeploymenttrue に設定します。

既にキー コンテナーがある場合は、テンプレートのデプロイが許可されていることを確認してください。

az keyvault update  --name ExampleVault --enabled-for-template-deployment true

新しいキー コンテナーを作成してシークレットを追加するには、次のように使用します。

az group create --name ExampleGroup --location centralus
az keyvault create \
  --name ExampleVault \
  --resource-group ExampleGroup \
  --location centralus \
  --enabled-for-template-deployment true
az keyvault secret set --vault-name ExampleVault --name "ExamplePassword" --value "hVFkk965BuUv"

キー コンテナーの所有者には、シークレットを作成するためのアクセスが自動的に付与されています。 シークレットを操作しているユーザーが、そのキー コンテナーの所有者でない場合、次を使用してアクセス許可を付与します。

az keyvault set-policy \
  --upn <user-principal-name> \
  --name ExampleVault \
  --secret-permissions set delete get list

キー コンテナーの作成とシークレットの追加の詳細については、次を参照してください。

シークレットへのアクセスを許可する

Bicep ファイルをデプロイするユーザーには、そのリソース グループとキー コンテナーのスコープで Microsoft.KeyVault/vaults/deploy/action のアクセス許可がある必要があります。 このアクセスは、所有者ロールと共同作成者ロールが許可します。 キー コンテナーの作成者である場合は、その所有者であり、そのアクセス許可を持っています。

次の手順は、最小限のアクセス許可を持つロールを作成する方法と、ユーザーを割り当てる方法を示します。

  1. カスタム ロール定義の JSON ファイルを作成します。

    {
      "Name": "Key Vault Bicep deployment operator",
      "IsCustom": true,
      "Description": "Lets you deploy a Bicep file with the access to the secrets in the Key Vault.",
      "Actions": [
        "Microsoft.KeyVault/vaults/deploy/action"
      ],
      "NotActions": [],
      "DataActions": [],
      "NotDataActions": [],
      "AssignableScopes": [
        "/subscriptions/00000000-0000-0000-0000-000000000000"
      ]
    }
    

    "00000000-0000-0000-0000-000000000000" はサブスクリプション ID に置き換えます。

  2. JSON ファイルを使用して新しいロールを作成します。

    az role definition create --role-definition "<path-to-role-file>"
    az role assignment create \
      --role "Key Vault Bicep deployment operator" \
      --scope /subscriptions/<Subscription-id>/resourceGroups/<resource-group-name> \
      --assignee <user-principal-name>
    

    このサンプルでは、リソース グループ レベルでカスタム ロールを割り当てます。

Managed Applications の Bicep ファイルでキー コンテナーを使用する場合は、アプライアンス リソース プロバイダー サービス プリンシパルにアクセス許可を付与する必要があります。 詳細については、「Access Key Vault secret when deploying Azure Managed Applications」(Azure Managed Applications のデプロイ時に Key Vault シークレットにアクセスする) を参照してください。

getSecret 関数を使用する

getSecret 関数を使用してキー コンテナーのシークレットを取得し、その値をモジュールの string パラメーターに渡すことができます。 getSecret 関数は Microsoft.KeyVault/vaults リソースでのみ呼び出すことができ、@secure() デコレーターのパラメーターと共にのみ使用できます。

次の Bicep ファイルによって、Azure SQL サーバーが作成されます。 adminPassword パラメーターには @secure() デコレーターがあります。

param sqlServerName string
param adminLogin string

@secure()
param adminPassword string

resource sqlServer 'Microsoft.Sql/servers@2020-11-01-preview' = {
  name: sqlServerName
  location: resourceGroup().location
  properties: {
    administratorLogin: adminLogin
    administratorLoginPassword: adminPassword
    version: '12.0'
  }
}

前の Bicep ファイルをモジュールとして使用してみましょう。ファイル名は、メインの Bicep ファイルと同じディレクトリにある sql.bicep です。

次の Bicep ファイルは、モジュールとして sql.bicep を使用します。 Bicep ファイルは既存のキー コンテナーを参照し、getSecret 関数を呼び出してキー コンテナーのシークレットを取得し、その値をパラメーターとしてモジュールに渡します。

param sqlServerName string
param adminLogin string

param subscriptionId string
param kvResourceGroup string
param kvName string

resource kv 'Microsoft.KeyVault/vaults@2023-02-01' existing = {
  name: kvName
  scope: resourceGroup(subscriptionId, kvResourceGroup )
}

module sql './sql.bicep' = {
  name: 'deploySQL'
  params: {
    sqlServerName: sqlServerName
    adminLogin: adminLogin
    adminPassword: kv.getSecret('vmAdminPassword')
  }
}

また、getSecret 関数 (または名前空間修飾子 az.getSecret を使用) を .bicepparam ファイルで使用して、キー コンテナーからシークレットの値を取得できます。

using './main.bicep'

param secureUserName = getSecret('exampleSubscription', 'exampleResourceGroup', 'exampleKeyVault', 'exampleSecretUserName', 'exampleSecretVersion')
param securePassword = az.getSecret('exampleSubscription', 'exampleResourceGroup', 'exampleKeyVault', 'exampleSecretPassword')

パラメーター ファイルのシークレットを参照する

モジュールを使用しない場合は、パラメーター ファイルで直接キー コンテナーを参照できます。 次の図は、パラメーター ファイルがシークレットを参照し、その値を Bicep ファイルに渡すしくみを示しています。

Resource Manager のキー コンテナー統合の図

注意

現在、JSON パラメーター ファイルでのみキー コンテナーを参照できます。 Bicep パラメーター ファイルでキー コンテナーを参照することはできません。

次の Bicep ファイルでは、管理者パスワードを含む SQL サーバーがデプロイされます。 パスワード パラメーターは、セキュリティで保護された文字列に設定されます。 しかし、Bicep には値がどこから来ているかが指定されていません。

param location string = resourceGroup().location
param adminLogin string

@secure()
param adminPassword string

param sqlServerName string

resource sqlServer 'Microsoft.Sql/servers@2022-11-01-preview' = {
  name: sqlServerName
  location: location
  properties: {
    administratorLogin: adminLogin
    administratorLoginPassword: adminPassword
    version: '12.0'
  }
}

ここで、前述の Bicep ファイルのパラメータ ファイルを作成します。 パラメーター ファイルでは、Bicep ファイルのパラメーターの名前と一致するパラメーターを指定します。 パラメーター値のために、キー コンテナーのシークレットを参照します。 シークレットを参照するには、Key Vault のリソース識別子とシークレットの名前を渡します。

次のパラメーター ファイルには、キー コンテナーのシークレットが既に存在している必要があり、そのリソース ID に対して静的な値を指定します。

{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "adminLogin": {
      "value": "exampleadmin"
    },
    "adminPassword": {
      "reference": {
        "keyVault": {
          "id": "/subscriptions/<subscription-id>/resourceGroups/<rg-name>/providers/Microsoft.KeyVault/vaults/<vault-name>"
        },
        "secretName": "ExamplePassword"
      }
    },
    "sqlServerName": {
      "value": "<your-server-name>"
    }
  }
}

現在のバージョン以外のバージョンのシークレットを使用する必要がある場合は、secretVersion プロパティを含めます。

"secretName": "ExamplePassword",
"secretVersion": "cd91b2b7e10e492ebb870a6ee0591b68"

テンプレートをデプロイし、パラメーター ファイルを渡します。

az group create --name SqlGroup --location westus2
az deployment group create \
  --resource-group SqlGroup \
  --template-file <Bicep-file> \
  --parameters <parameters-file>

次のステップ