前の記事
以前BicepでデプロイしたAzure VMですが、
デプロイ時のPowerShellのコマンドに管理者ユーザーとパスワードを設定する必要があります。
# パラメータをハッシュテーブルまたはインラインで指定する例
Connect-AzAccount
New-AzResourceGroup -Name rg-vmdeploy-bicep -Location "Japan East"
# $HOME\.azure\bin を現在のセッションのPATHに一時的に追加
$env:Path += ";$HOME\.azure\bin"
$parameters = @{
vmName = 'vm-deploy-bicep'
adminUsername = 'XXXXX'
adminPassword = 'YYYYY'
location = 'japaneast'
}
New-AzResourceGroupDeployment -ResourceGroupName rg-vmdeploy-bicep `
-TemplateFile main.bicep `
-TemplateParameterObject $parameters
コマンドもGitHubで保管しているのと、資格情報をハードコーディングしているので、
このままではVMの管理者ユーザーが駄々洩れです。
改善策はいろいろある気がしますが、今回はAzureのキーコンテナーを使ってみます。
Azure キーコンテナー(Key Vault)
資格情報や証明書を安全に管理するためのコンテナです。
基本はRBACで権限を持った人にのみ機密情報を渡せるようになります。
キーコンテナーへのアクセスはサブスクリプションの所有者権限だけではNGで、キーコンテナー専用のRBACがあるので、適切に付与していきましょう。
<参考>キーコンテナーのRBAC一部抜粋


キーコンテナーのデプロイ
- キーコンテナーを作成
- シークレットの登録
- VMデプロイのコマンドを修正
という流れにしないといけないため、先にキーコンテナーのリソースを作成します。
keyvault.bicep
// keyvault/keyvault.bicep
@description('デプロイする場所 (リージョン)')
param location string = resourceGroup().location
@description('Key Vault名。グローバルで一意である必要があります。')
param keyVaultName string
@description('Key Vaultへのアクセスを許可するユーザー/SPのオブジェクトID')
param principalId string
// Key Vault のリソース定義
resource keyVault 'Microsoft.KeyVault/vaults@2023-07-01' = {
name: keyVaultName
location: location
properties: {
tenantId: subscription().tenantId
sku: {
family: 'A'
name: 'standard'
}
enableSoftDelete: true
softDeleteRetentionInDays: 7
// アクセス設定
accessPolicies: [
{
objectId: principalId
tenantId: subscription().tenantId
permissions: {
secrets: [
'get' // VMパスワードの取得権限
]
}
}
]
}
}
// Key VaultのリソースIDを外部に出力
output keyVaultId string = keyVault.id
permissionでgetのみ指定していますが、これだとシークレットの読み込みだけで後工程のシークレットの登録ができないため、権限を振り直す必要があります。
また、シークレット情報の登録はコードでやると結局意味ないので、登録のみポータルから行います。
IAMの設定
まずは権限の振り直しをします。
ポータルからキーコンテナのIAMに移動してロール割り当ての追加。

いろいろ出てくるので必要なものを選んで割り当ててください。
Key Vault表記だったりキー コンテナー表記だったりブレてるので、求めてるものがなければ英⇔カナを変えてみたりしてください。

シークレットの登録
続いて、シークレットを登録します。リソースのオブジェクトから「シークレット」を選択して生成します。
シークレットはキーバリューの形式で保存されるため、
管理者IDと管理者パスワードを紐づけて保管するということはできません。

ここで指定する「名前」はあくまでこのシークレットにつける名前なので、ユーザーIDとしての保管ではないです。
今回はとりあえずWindowsServerのパスワードだけ「vm-admin-password」という名前で作成しました。

PowerShellコマンドでシークレットを呼び出す
VMを作成するPowerShellコマンドは以下のようになります。
# Key Vault IDの取得
$existingKeyVaultId = (Get-AzKeyVault -VaultName $keyVaultName).ResourceId
# $HOME\.azure\bin を現在のセッションのPATHに一時的に追加
$env:Path += ";$HOME\.azure\bin"
$vmParameters = @{
vmName = "vm-deploy-bicep"
adminUsername = "adminUser"
existingKeyVaultId = $existingKeyVaultId
adminPasswordSecretName = "vm-admin-password"
location = $location
}
キーコンテナーのリソースIDを取得して、そのリソースIDの中にあるvm-admin-passwordの情報をシークレットとして利用するという流れです。
また、呼び出されるmain.bicepにも変更が必要です。
キーコンテナーを参照し、VMの管理者パスワードを設定しています。
main.bicep
// main.bicep
@description('デプロイする場所 (リージョン)')
param location string = resourceGroup().location
// --- 必須パラメータ ---
@description('VM名')
param vmName string
@description('管理者ユーザー名')
param adminUsername string
// --- Key Vault 関連パラメータ (外部からIDを受け取る) ---
@description('既に作成されているKey Vaultの完全なリソースID')
param existingKeyVaultId string
@description('Key Vaultに保存されているVM管理者パスワードのシークレット名')
param adminPasswordSecretName string = 'vm-admin-password'
// --- ネットワーク/VM設定パラメータ ---
@description('仮想ネットワーク名')
param vnetName string = 'vnet-deploy-bicep'
@description('サブネット名')
param subnetName string = 'subnet-deploy-bicep'
@description('NIC名')
param nicName string = 'nic-deploy-bicep'
@description('VMのサイズ (例: Standard_B1s)')
param vmSize string = 'Standard_B1s'
// --- Key Vault 参照の準備 ---
// Key Vault IDから Key Vault 名を抽出
var keyVaultName = last(split(existingKeyVaultId, '/'))
// Key Vault のプロバイダー情報を取得するための変数 (Bicepが参照を解決するために必要)
// Bicepでは外部リソースへの参照に `resourceId()` が使われますが、Key Vault参照には特殊な構文が必要です。
var keyVaultReference = resourceId(
subscription().subscriptionId,
resourceGroup().name,
'Microsoft.KeyVault/vaults',
keyVaultName
)
// 1. 仮想ネットワークモジュールのデプロイ
module vnetModule 'modules/vnet.bicep' = {
name: 'vnet-deployment'
params: {
location: location
vnetName: vnetName
subnetName: subnetName
}
}
// 2. ネットワークインターフェースモジュールのデプロイ
module nicModule 'modules/nic.bicep' = {
name: 'nic-deployment'
params: {
location: location
nicName: nicName
// VNetモジュールの出力からサブネットIDを取得
subnetId: vnetModule.outputs.subnetId
}
}
// 3. 仮想マシンモジュールのデプロイ
module vmModule 'modules/vm.bicep' = {
name: 'vm-deployment'
params: {
location: location
vmName: vmName
adminUsername: adminUsername
vmSize: vmSize
nicId: nicModule.outputs.nicId
// Key Vault 参照をシークレットURIとしてVMモジュールに渡す
// この構文により、デプロイ時にAzure Resource ManagerがKey Vaultからシークレットを取得します。
adminPassword: '[reference(\'${keyVaultReference}\', \'2023-07-01\').secretUriWithVersion(\'${adminPasswordSecretName}\')]'
}
}
// 最終的なVM IDを出力
output virtualMachineId string = vmModule.outputs.vmId
これで、PowerShellコマンドを実行したところデプロイは正常に完了しました。
確認作業をしようとすると、デプロイしたWindowsServerにパブリックIPが割り当てられていないことが判明したため、NICの設定を少し変更しようと思います。
ということで、次回は設定変更とBicep冪等性について確認します。



コメント