Bicep を使用してシークレットを管理する
デプロイにおいて、セキュリティで保護された形でシークレットを保存し、Azure 環境全体に伝達することが必要な場合はよくあります。 Bicep と Azure では、デプロイでシークレットを管理するのに役立つ多くの機能が提供されます。
可能であればシークレットを避ける
多くの状況で、シークレットを一切使わないことは可能です。 多くの Azure リソースでマネージド ID がサポートされており、資格情報を処理または管理しなくても、リソースで Azure 内の他のリソースへのアクセスを認証および認可できるようになっています。 さらに、一部の Azure サービスでは、HTTPS 証明書を自動で生成できるため、証明書や秘密キーを取り扱う必要がありません。 可能な限り、マネージド ID とサービス管理の証明書を使用してください。
セキュリティで保護されたパラメーターを使用する
Bicep デプロイにパラメーターとしてシークレットを提供する必要がある場合、@secure()
デコレーターを使用します。 パラメーターをセキュアとマークすると、Azure Resource Manager では、値をログに記録したり、Azure portal、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 ファイルは Networking という名前のリソース グループにデプロイされています。 モジュールのパラメーター mySecret の値は、Secrets リソース グループにある contosonetworkingsecrets という名前のキー コンテナーで定義されています。
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
関数を使用してセキュリティで保護されたパラメーターを提供できます。
サブスクリプション ID、リソース グループ名、キー コンテナー名を指定して KeyVault を参照します。 シークレット名を指定すると、シークレットの値を取得できます。 必要に応じて、シークレットのバージョンを指定できます。 シークレットのバージョンを指定しない場合は、最新のバージョンが使用されます。
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