Description
Ideally, all our modules should use the same interface for customer managed keys. For example input parameters such as:
@description('Optional. Enable service encryption.')
param enableEncryption bool = true
@description('Optional. The resource ID of a key vault to reference a customer managed key for encryption from.')
param cMKKeyVaultResourceId string = ''
@description('Optional. The name of the customer managed key to use for encryption.')
param cMKKeyName string = ''
@description('Conditional. User assigned identity to use when fetching the customer managed key. If not provided, a system-assigned identity can be used - but must be given access to the referenced key vault first.')
param cMKUserAssignedIdentityResourceId string = ''
@description('Optional. The version of the customer managed key to reference for encryption. If not provided, the latest key version is used.')
param cMKKeyVersion string = ''
And also the implementation inside the module should ideally be similar. Note however, this cannot always be achieved as each provider has a different interpretation, and e.g. identities sometimes require a resource ID, sometimes a client ID, properties are in different locations, versions are required/not, etc. However, if we can shield the consumer as much as possible, the user experience will be a lot better.
- As a first step, we should agree on an interface (e.g. the parameter above)
- Then we should decide on some fundamental inside the module. E.g. how to not deploy encryption, how to do it with Azure-manged keys, and how to do it with customer-manged keys. For example
// Note this is just a mockup
encryption: enableEncryption && !empty(cMKKeyName) ? {
// Customer-managed key
keySource: 'Microsoft.KeyVault'
keyVaultProperties: {
identityClientId: !empty(cMKUserAssignedIdentityResourceId ) ? cmkUserAssignedIdentity.properties.clientId : null
keyVaultUri: cmkKeyVault.properties.vaultUri
keyName: cMKKeyName
keyVersion: cMKKeyVersion
}
} : enableEncryption ? {
// Service-managed key
keySource: 'Microsoft.CognitiveServices/accounts'
} : null
Further, we can use the following snippet to lift the burder for users to specify key versions:
resource cMKKeyVaultKey 'Microsoft.KeyVault/vaults/keys@2021-10-01' existing = if (!empty(cMKKeyVaultResourceId) && !empty(cMKKeyName)) {
name: '${last(split(cMKKeyVaultResourceId, '/'))}/${cMKKeyName}'
scope: resourceGroup(split(cMKKeyVaultResourceId, '/')[2], split(cMKKeyVaultResourceId, '/')[4])
}
# Allows the use of
keyUrl: !empty(cMKKeyVersion) ? '${cMKKeyVaultKey.properties.keyUri}/${cMKKeyVersion}' : cMKKeyVaultKey.properties.keyUriWithVersion
Description
Ideally, all our modules should use the same interface for customer managed keys. For example input parameters such as:
And also the implementation inside the module should ideally be similar. Note however, this cannot always be achieved as each provider has a different interpretation, and e.g. identities sometimes require a resource ID, sometimes a client ID, properties are in different locations, versions are required/not, etc. However, if we can shield the consumer as much as possible, the user experience will be a lot better.
Further, we can use the following snippet to lift the burder for users to specify key versions: