状況に応じて App Service へ Key Vault の権限を付与する Bicep を書いていたところ、ちょっと詰まったので備忘録
何がしたいのか?
App Service 作成時、パラメータで Key Vault の名前が渡された時だけ Key Vault の権限を設定したい
うまく動かなかった Bicep
keyVaultName が空じゃない場合のみ、アクセスポリシーをデプロイしたいという気持ちで書いたので、次のようにしてみました。
resource kvAccessPolicy 'Microsoft.KeyVault/vaults/accessPolicies@2022-07-01' = if(!empty(keyVaultName)) {
name: '${keyVaultName}/add'
properties: {
accessPolicies: [
{
objectId: app.identity.principalId
tenantId: app.identity.tenantId
permissions: {
secrets: [
'get'
'list'
]
keys: [
'get'
'list'
]
certificates: [
'get'
'list'
]
}
}
]
}
}
何で詰まったのか
ARM テンプレート上で Key Vault の名前を使ってリソースを組み立てようとするので、 Key Vault 名が空だとフォーマットエラーになるようです。
アクセスポリシーは、子要素なので、通常 KeyVault名/add のようになるところが、/add と組み立てられるため、フォーマットエラーとして認識されます。
A nested resource type must have identical number of segments as its resource name. A root resource type must have segment length one greater than its resource name.
ARM テンプレートは、次のように展開されます。
{
"condition": "[not(empty(parameters('keyVaultName')))]",
"type": "Microsoft.KeyVault/vaults/accessPolicies",
"apiVersion": "2022-07-01",
"name": "[format('{0}/{1}', parameters('keyVaultName'), 'add')]",
"properties": {
"accessPolicies": [
{
"objectId": "[reference(resourceId('Microsoft.Web/sites', format('app-{0}-{1}-{2}-{3}', parameters('workload'), parameters('tenant'), parameters('env'), parameters('location'))), '2022-03-01', 'full').identity.principalId]",
"tenantId": "[reference(resourceId('Microsoft.Web/sites', format('app-{0}-{1}-{2}-{3}', parameters('workload'), parameters('tenant'), parameters('env'), parameters('location'))), '2022-03-01', 'full').identity.tenantId]",
"permissions": {
"secrets": [
"get",
"list"
]
}
}
]
},
"dependsOn": [
"[resourceId('Microsoft.Web/sites', format('app-{0}-{1}-{2}-{3}', parameters('workload'), parameters('tenant'), parameters('env'), parameters('location')))]"
]
},
解決策
module に実装を押し込みました。
モジュールは次の通り
param keyVaultName string
param objectId string
param tenantId string
@allowed([
'get'
'list'
'all'
'backup'
'delete'
'purge'
'recover'
'restore'
'set'
])
param secrets array
@allowed([
'get'
'list'
'all'
'backup'
'create'
'decrypt'
'delete'
'encrypt'
'getrotationpolicy'
'import'
'list'
'purge'
'recover'
'release'
'restore'
'rotate'
'setrotationpolicy'
'sign'
'unwrapKey'
'update'
'verify'
'wrapKey'
])
param keys array
@allowed([
'get'
'list'
'all'
'backup'
'create'
'delete'
'deleteissuers'
'getissuers'
'import'
'listissuers'
'managecontacts'
'manageissuers'
'purge'
'recover'
'restore'
'setissuers'
'update'
])
param certificates array
resource kvAccessPolicy 'Microsoft.KeyVault/vaults/accessPolicies@2022-07-01' = {
name: '${keyVaultName}/add'
properties: {
accessPolicies: [
{
objectId: objectId
tenantId: tenantId
permissions: {
secrets: secrets
keys: keys
certificates: certificates
}
}
]
}
}
これだと、ARM テンプレートに展開された際に、モジュール呼び出し時の name が name プロパティに差し込まれるのでフォーマットエラーにならないようです。
※ ほんとにこれが根本原因なのかは、ちょっと自信ない
まとめ
Bicep は、結構はまりどころが多いですが、慣れると便利