I've managed to create a solution to first read the AccessPolicies, if the KeyVault resource exists, and then use these as a parameter. For this I used the following scripts. Please note: that you cannot merge this logic into one file, otherwise you will get errors.
In this example, the name of the KeyVault resource is: 'MyKeyVault' and my user-assigned managed identity is: 'MyUserAssignedManagedIdentity'. This Identity has the reader role on the ResourceGroup in Azure of the KeyVault resource.
These scripts work in the case that the KeyVault doesn't exist and when it already exists. When it exisits it preserves the AccessPolicies.
File 1: MainDeployment.bicep (Your starting point script)
var location = resourceGroup().location
var keyVaultName = 'MyKeyVault'
module keyVaultModule 'KeyVaultResourcePreservingAccessPolicies.bicep' = {
name: 'keyVaultResourcePreservingAccessPolicies_${uniqueString(keyVaultName)}'
params: {
location: location
keyVaultName: keyVaultName
}
}
File 2: KeyVaultResourcePreservingAccessPolicies.bicep:
param location string
param keyVaultName string
module resourceExistsModule 'ResourceExists.bicep' = {
name: 'resourceExists_${uniqueString(keyVaultName)}'
params: {
location: location
resourceName: keyVaultName
// User assigned managed identity that is used to execute the deployment script on the resource group
// User assigned Managed Identity info: https://learn.microsoft.com/en-us/azure/active-directory/managed-identities-azure-resources/overview
// User assigned Managed Identity needs reader role on the resource group of the resource (See Access Policies of the resource group)
identityPrincipalId: 'MyUserAssignedManagedIdentity'
}
}
module keyVaultModule 'KeyVaultResourceUsingExistingAccessPolicies.bicep' = {
name: 'keyVaultResourceUsingExistingAccessPolicies_${uniqueString(keyVaultName)}'
params: {
location: location
keyVaultName: keyVaultName
keyVaultResourceExists: resourceExistsModule.outputs.exists
}
}
File 3: KeyVaultResourceUsingExistingAccessPolicies.bicep
param location string
param keyVaultName string
param keyVaultResourceExists bool
resource existingKeyVaultResource 'Microsoft.KeyVault/vaults@2021-11-01-preview' existing = if (keyVaultResourceExists) {
name: keyVaultName
}
module keyVaultModule 'KeyVaultResource.bicep' = {
name: 'KeyVaultResource_${uniqueString(keyVaultName)}'
params: {
location: location
keyVaultName: keyVaultName
accessPolicies: keyVaultResourceExists ? existingKeyVaultResource.properties.accessPolicies : []
}
dependsOn: [
existingKeyVaultResource
]
}
File 4: ResourceExists.bicep:
// Based on https://github.com/olafloogman/BicepModules/blob/main/resource-exists.bicep and https://ochzhen.com/blog/check-if-resource-exists-azure-bicep
@description('Resource name to check in current scope (resource group)')
param resourceName string
@description('Resource ID of user managed identity with reader permissions in current scope')
param identityPrincipalId string
param location string
param utcValue string = utcNow()
var userAssignedIdentity = resourceId(subscription().subscriptionId, resourceGroup().name, 'Microsoft.ManagedIdentity/userAssignedIdentities', '${identityPrincipalId}')
// The script below performs an 'az resource list' command to determine whether a resource exists
resource resource_exists_script 'Microsoft.Resources/deploymentScripts@2020-10-01' = {
name: 'resourceExistsDeploymentScript_${resourceName}'
location: location
kind: 'AzureCLI'
identity: {
type: 'UserAssigned'
userAssignedIdentities: {
'${userAssignedIdentity}': {}
}
}
properties: {
forceUpdateTag: utcValue
azCliVersion: '2.15.0'
timeout: 'PT10M'
scriptContent: 'result=$(az resource list --resource-group ${resourceGroup().name} --name ${resourceName}); echo $result; echo $result | jq -c \'{Result: map({name: .name})}\' > $AZ_SCRIPTS_OUTPUT_PATH;'
cleanupPreference: 'OnSuccess'
retentionInterval: 'P1D'
}
}
//Script returns something like: //[{"name":"MyKeyVault"}]
output exists bool = length(resource_exists_script.properties.outputs.Result) > 0
File 5: KeyVaultResource.bicep
param location string
param keyVaultName string
param accessPolicies array
resource keyVaultResource 'Microsoft.KeyVault/vaults@2021-11-01-preview' = {
name: keyVaultName
location: location
properties: {
sku: {
family: 'A'
name: 'standard'
}
accessPolicies: accessPolicies
tenantId: subscription().tenantId
enableSoftDelete: true
softDeleteRetentionInDays: 90
enableRbacAuthorization: false
enablePurgeProtection: true
publicNetworkAccess: 'Enabled'
}
}