Bicep使うときに[KeyVault].getSecret()の類に気を付けような
モチベ
Azure Key Vaultを参照するインフラのデプロイが厄介だと聞き、ちょっと試してみたところ思ったより厄介だったので試したことを順番に記録していく
実現したいこと
1回のデプロイの中で、
- Key Vaultをデプロイし
- Key VaultにシークレットとしてVMの管理者パスワードを格納し
- そのシークレットを参照する形でVMを作成する
ソース
諸々の試行錯誤の後に出来上がったものにはなるが、ソースとしてはこちら
注意事項
手順3でKey Vaultのシークレットを参照する際、getSecret()
のような関数を利用するのだが、これはmoduleの変数として渡す必要があり、例えばvm.bicep
の中で利用することができないという制約がある(なぜ)。
module CreateVM './modules/vm.bicep' = {
name: 'create-vm-module'
params: {
location: resourceGroup().location
vmName: vmName
vnetName: vnetName
subnetName: subnetName
vmAdminUserName: vmAdminUserName
vmAdminPassword: keyVault.getSecret('vmAdminPassword')
}
dependsOn: [
CreateVnet
]
}
やってみる
最初の取り組み
- 構成自体はシンプルなため、とりあえず以下のイメージでBicepファイル群を構成し、Azure CLIにてデプロイする
-
main.bicep
ではKeyVaultの作成も実施している。
main.bicep
Modules/
∟vnet.bicep
∟vm.bicep
- デプロイしてみると、以下のようなエラーとともに終了
- 依存関係的には先にKey Vaultを作っているので問題ないはずと思いつつ、公式ドキュメントを見てみると
existing =
で参照しているので、同じbicep上でKey Vaultの作成と呼び出しを行っているのがよくないのかと思い、そこを分割しようとするのが次の取り組み
{"code": "KeyVaultParameterReferenceNotFound", "message": "The specified KeyVault '/subscriptions/<subID>/resourceGroups/20230823-bicepvmwithkv/providers/Microsoft.KeyVault/vaults/kv-cloud' could not be found. Please see https://aka.ms/arm-keyvault for usage details."}
Key Vaultの作成の分離
先の事情によりgetStart.bicep
を作成し、そこでKey Vaultの作成と、main.bicep
の呼び出しを行うように変更した。実行すると、同様のエラーで終了。デプロイに際してARMテンプレートが生成されるので結果が同じであることは目に見えていたが…一応。
エラー調査
KeyVault Bicep getSecret Notfound
等で検索すると、結構出てきた。KeyVaultの作成と参照を一連のデプロイの中でできずに悩んでいる同志が結構いる模様。
-
コメントを追っていくと、表現を借りるとやはり
preflight validation
によってデプロイ前にブロックされている、という認識はあっていそう -
BicepではTerraformのような状態管理の仕組みが存在しないため、デプロイ前の静的チェックが厳密に行われるのかもしれない
-
とはいえ、同僚は同様の構造でデプロイできていると聞いていたため、同僚のやり方倣ってAzure CLIではなく、VSCode上でBicepファイルを直接デプロイするという方法でデプロイを投げてみた
-
すると、すんなりデプロイできてしまった
-
てことはつまり、Azure CLIでのバリデーションの問題なのか…?ということでKeyVaultの作成も
main.bicep
に含めてしまってもいいはずという考えから、main.bicep
でKey Vaultの作成も実行するパターンで、VSCodeからBicepをデプロイ -
すると、成功
-
結果から見るに、
.getSecret()
とAzure CLIの相性がよくない(過剰にvalidationがかかる)ということになる
Azure PowerShellならどうか
- Azure PowerShellでもAzure CLIと同様のエラーが出た
- KeyVaultが見つからないと言われる
New-AzResourceGroupDeployment : 10:47:48 - Error: Code=KeyVaultParameterReferenceNotFound; Message=The specified KeyVault '/subscriptions/<subID>/resourceGroups/20230824-depbyps/providers/Microsoft.KeyVault/vaults/kv-cloud-inckv' could not be found.
まとめ
- つまり、現状Key Vaultのデプロイとインフラのデプロイを一挙にやりたい場合には、Visual Studio Codeにて右クリックでデプロイするしかないということになってしまう
- 右クリックでのデプロイであれば、おそらく
Preflight Validation
が回避されてデプロイできるという検証結果になった、なんとも微妙な挙動 - とはいえ、本筋としてはAzure CLI/PowerShellから叩くやり方になるはずなので、Bicepの思想としてKey Vaultのデプロイとインフラのデプロイを分離しろというのがあるかもしれない
おわり
- Bicep、便利で面白いけどたまに不安になる
-
[KeyVault].getSecret()
以外にも、このような挙動をするものはありそう
Discussion