'Retrieving key vault secret from a keyvault created in same bicep
I have an issue similar to Retrieve a secret from keyvault in Bicep and use as input for Synapse Workspace creation
(Though I can’t continue the discussion there since I don’t have enough rep)
I need to have keyvault's and vm's created in the same bicep deployment template file. A secret generated in keyvault bicep module file should be used to set the password for local admin for the VM. All though it is not a requirement that the secret must be created at keyvault module level, I dont see any other way in order for the deployment to be secure.
This is the relevant part of the main bicep template:
module kv './modules/keyvault.bicep' = {
name: '${deployment().name}-kv'
scope: rg
params: {
keyvaultName: kvName
createLocalAdmin: true
}
}
resource kvRef 'Microsoft.KeyVault/vaults@2019-09-01' existing = {
name: kvName
scope: rg
}
module vm './modules/vm.bicep' = {
name: '${deployment().name}-vm-${vm.hostShortName}'
scope: rg
params: {
adminPassword: kvRef.getSecret('localadmin')
adminUsername: 'localadmin'
}
dependsOn: [
network
kv
]
}
The challenge here is that when the bicep is deployed I get error: The specified KeyVault '<KEYVAULT_ID>’ could not be found. If I replace kvRef.getSecret('localadmin') with random valued string, the template is working fine.
In ARM template this can be solved with for example:
"adminPassword": {"Value":{
"reference": {
"keyVault": {
"id":"concat(subscription().Id,'/resourceGroups/',variables('rgName'),'/providers/Microsoft.KeyVault/vaults/',reference('deploy-keyvault').outputs.KeyvaultName.value)]"
},
"secretName": "[variables('localAdminSecretname')]"
}
}
}
Is there any way to do the same approach in bicep as the ARM example or solve this in any other way?
Solution 1:[1]
This is an order of operations/parallelism problem.
module kv './modules/keyvault.bicep' = {
name: '${deployment().name}-kv'
scope: rg
params: {
keyvaultName: kvName
createLocalAdmin: true
}
}
resource kvRef 'Microsoft.KeyVault/vaults@2019-09-01' existing = {
name: kvName
scope: rg
}
Each module runs as a sub-deployment, potentially in parallel. Bicep relies on reference usage to generate dependsOn references. i.e. if you had your module output a name property, then reference it as follows:
resource kvRef 'Microsoft.KeyVault/vaults@2019-09-01' existing = {
name: kv.outputs.name
scope: rg
}
Bicep would be able to understand that one has to run before the other automatically. Since you're not doing that, you have to explicitly tell it.
The solution is to add a dependsOn to your existing keyvault, so it knows to wait for the prior module to complete.
resource kvRef 'Microsoft.KeyVault/vaults@2019-09-01' existing = {
name: kvName
scope: rg
dependsOn: [ kv ]
}
Solution 2:[2]
Maybe you can consider splitting the deployment of Key Vault and the resources that need the instance you have just created like this:
https://github.com/mariomeyrelles/bicep-functions-cosmos-keyvault/blob/main/src/main.bicep
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Daniel Mann |
| Solution 2 | Mário Meyrelles |
