Skip to content
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
196 changes: 134 additions & 62 deletions internal/services/databricks/databricks_workspace_resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,12 @@ import (
"github.com/hashicorp/go-azure-helpers/lang/response"
"github.com/hashicorp/go-azure-helpers/resourcemanager/commonids"
"github.com/hashicorp/go-azure-helpers/resourcemanager/commonschema"
"github.com/hashicorp/go-azure-helpers/resourcemanager/keyvault"
"github.com/hashicorp/go-azure-helpers/resourcemanager/location"
"github.com/hashicorp/go-azure-helpers/resourcemanager/tags"
"github.com/hashicorp/go-azure-sdk/resource-manager/databricks/2022-10-01-preview/accessconnector"
"github.com/hashicorp/go-azure-sdk/resource-manager/databricks/2024-05-01/workspaces"
"github.com/hashicorp/go-azure-sdk/resource-manager/keyvault/2023-07-01/managedhsms"
mlworkspace "github.com/hashicorp/go-azure-sdk/resource-manager/machinelearningservices/2025-06-01/workspaces"
"github.com/hashicorp/go-azure-sdk/resource-manager/network/2023-09-01/loadbalancers"
"github.com/hashicorp/go-azure-sdk/resource-manager/network/2025-01-01/subnets"
Expand All @@ -27,8 +29,6 @@ import (
"github.com/hashicorp/terraform-provider-azurerm/internal/clients"
"github.com/hashicorp/terraform-provider-azurerm/internal/locks"
"github.com/hashicorp/terraform-provider-azurerm/internal/services/databricks/validate"
keyVaultParse "github.com/hashicorp/terraform-provider-azurerm/internal/services/keyvault/parse"
keyVaultValidate "github.com/hashicorp/terraform-provider-azurerm/internal/services/keyvault/validate"
resourcesParse "github.com/hashicorp/terraform-provider-azurerm/internal/services/resource/parse"
storageValidate "github.com/hashicorp/terraform-provider-azurerm/internal/services/storage/validate"
"github.com/hashicorp/terraform-provider-azurerm/internal/tf/pluginsdk"
Expand Down Expand Up @@ -281,24 +281,24 @@ func resourceDatabricksWorkspace() *pluginsdk.Resource {
"managed_services_cmk_key_vault_key_id": {
Type: pluginsdk.TypeString,
Optional: true,
ValidateFunc: keyVaultValidate.KeyVaultChildID,
ValidateFunc: keyvault.ValidateNestedItemID(keyvault.VersionTypeVersioned, keyvault.NestedItemTypeKey),
},

"managed_services_cmk_key_vault_id": {
Type: pluginsdk.TypeString,
Optional: true,
ValidateFunc: commonids.ValidateKeyVaultID,
ValidateFunc: validation.Any(commonids.ValidateKeyVaultID, managedhsms.ValidateManagedHSMID),
},

"managed_disk_cmk_key_vault_key_id": {
Type: pluginsdk.TypeString,
Optional: true,
ValidateFunc: keyVaultValidate.KeyVaultChildID,
ValidateFunc: keyvault.ValidateNestedItemID(keyvault.VersionTypeVersioned, keyvault.NestedItemTypeKey),
},
"managed_disk_cmk_key_vault_id": {
Type: pluginsdk.TypeString,
Optional: true,
ValidateFunc: commonids.ValidateKeyVaultID,
ValidateFunc: validation.Any(commonids.ValidateKeyVaultID, managedhsms.ValidateManagedHSMID),
},

"managed_disk_cmk_rotation_to_latest_version_enabled": {
Expand Down Expand Up @@ -466,6 +466,7 @@ func resourceDatabricksWorkspaceCreate(d *pluginsdk.ResourceData, meta interface
lbClient := meta.(*clients.Client).LoadBalancers.LoadBalancersClient
subnetsClient := meta.(*clients.Client).Network.Subnets
keyVaultsClient := meta.(*clients.Client).KeyVault
managedHSMsClient := meta.(*clients.Client).ManagedHSMs
subscriptionId := meta.(*clients.Client).Account.SubscriptionId
ctx, cancel := timeouts.ForCreate(meta.(*clients.Client).StopContext, d)
defer cancel()
Expand All @@ -485,7 +486,6 @@ func resourceDatabricksWorkspaceCreate(d *pluginsdk.ResourceData, meta interface
var backendPoolName, loadBalancerId string
skuName := d.Get("sku").(string)
managedResourceGroupName := d.Get("managed_resource_group_name").(string)
location := location.Normalize(d.Get("location").(string))
backendPool := d.Get("load_balancer_backend_address_pool_id").(string)

if backendPool != "" {
Expand Down Expand Up @@ -595,69 +595,104 @@ func resourceDatabricksWorkspaceCreate(d *pluginsdk.ResourceData, meta interface
diskResourceSubscriptionId := commonids.NewSubscriptionID(id.SubscriptionId)

if servicesKeyVaultId != "" {
// If they passed the 'managed_cmk_key_vault_id' parse the Key Vault ID
// to extract the correct key vault subscription for the exists call...
v, err := commonids.ParseKeyVaultID(servicesKeyVaultId)
if err != nil {
return fmt.Errorf("parsing %q as a Key Vault ID: %+v", servicesKeyVaultId, err)
}
// Parse the Key Vault or Managed HSM ID to extract the correct subscription for the exists call.
if v, err := commonids.ParseKeyVaultID(servicesKeyVaultId); err == nil {
servicesResourceSubscriptionId = commonids.NewSubscriptionID(v.SubscriptionId)
} else {
managedHsmId, managedHsmErr := managedhsms.ParseManagedHSMID(servicesKeyVaultId)
if managedHsmErr != nil {
return fmt.Errorf("parsing %q as a Key Vault or Managed HSM ID: %v; %v", servicesKeyVaultId, err, managedHsmErr)
}

servicesResourceSubscriptionId = commonids.NewSubscriptionID(v.SubscriptionId)
servicesResourceSubscriptionId = commonids.NewSubscriptionID(managedHsmId.SubscriptionId)
}
}

if servicesKeyId != "" {
setEncrypt = true
key, err := keyVaultParse.ParseNestedItemID(servicesKeyId)
key, err := keyvault.ParseNestedItemID(servicesKeyId, keyvault.VersionTypeAny, keyvault.NestedItemTypeKey)
if err != nil {
return err
}

// make sure the key vault exists
_, err = keyVaultsClient.KeyVaultIDFromBaseUrl(ctx, servicesResourceSubscriptionId, key.KeyVaultBaseUrl)
if err != nil {
return fmt.Errorf("retrieving the Resource ID for the customer-managed keys for managed services Key Vault in subscription %q at URL %q: %+v", servicesResourceSubscriptionId, key.KeyVaultBaseUrl, err)
if key.IsManagedHSM() {
domainSuffix, ok := meta.(*clients.Client).Account.Environment.ManagedHSM.DomainSuffix()
if !ok {
return fmt.Errorf("could not determine Managed HSM domain suffix for environment %q", meta.(*clients.Client).Account.Environment.Name)
}

managedHsmId, err := managedHSMsClient.ManagedHSMIDFromBaseUrl(ctx, servicesResourceSubscriptionId, key.KeyVaultBaseURL, domainSuffix)
if err != nil {
return fmt.Errorf("retrieving managed service Managed HSM at URL %q: %+v", key.KeyVaultBaseURL, err)
}
if managedHsmId == nil {
return fmt.Errorf("retrieving managed service Managed HSM at URL %q: not found", key.KeyVaultBaseURL)
}
} else {
// make sure the key vault exists
if _, err = keyVaultsClient.KeyVaultIDFromBaseUrl(ctx, servicesResourceSubscriptionId, key.KeyVaultBaseURL); err != nil {
return fmt.Errorf("retrieving Key Vault at URL %q: %+v", key.KeyVaultBaseURL, err)
}
}

encrypt.Entities.ManagedServices = &workspaces.EncryptionV2{
KeySource: workspaces.EncryptionKeySourceMicrosoftPointKeyvault,
KeyVaultProperties: &workspaces.EncryptionV2KeyVaultProperties{
KeyName: key.Name,
KeyVersion: key.Version,
KeyVaultUri: key.KeyVaultBaseUrl,
KeyVaultUri: key.KeyVaultBaseURL,
},
}
}

if diskKeyVaultId != "" {
// If they passed the 'managed_disk_cmk_key_vault_id' parse the Key Vault ID
// to extract the correct key vault subscription for the exists call...
v, err := commonids.ParseKeyVaultID(diskKeyVaultId)
if err != nil {
return fmt.Errorf("parsing %q as a Key Vault ID: %+v", diskKeyVaultId, err)
}
// If they passed the 'managed_disk_cmk_key_vault_id' parse the Key Vault or Managed HSM ID
// to extract the correct subscription for the exists call...
if v, err := commonids.ParseKeyVaultID(diskKeyVaultId); err == nil {
diskResourceSubscriptionId = commonids.NewSubscriptionID(v.SubscriptionId)
} else {
managedHsmId, managedHsmErr := managedhsms.ParseManagedHSMID(diskKeyVaultId)
if managedHsmErr != nil {
return fmt.Errorf("parsing %q as a Key Vault or Managed HSM ID: %v; %v", diskKeyVaultId, err, managedHsmErr)
}

diskResourceSubscriptionId = commonids.NewSubscriptionID(v.SubscriptionId)
diskResourceSubscriptionId = commonids.NewSubscriptionID(managedHsmId.SubscriptionId)
}
}

if diskKeyId != "" {
setEncrypt = true
key, err := keyVaultParse.ParseNestedItemID(diskKeyId)
key, err := keyvault.ParseNestedItemID(diskKeyId, keyvault.VersionTypeAny, keyvault.NestedItemTypeKey)
if err != nil {
return err
}

// make sure the key vault exists
_, err = keyVaultsClient.KeyVaultIDFromBaseUrl(ctx, diskResourceSubscriptionId, key.KeyVaultBaseUrl)
if err != nil {
return fmt.Errorf("retrieving the Resource ID for the customer-managed keys for managed disk Key Vault in subscription %q at URL %q: %+v", diskResourceSubscriptionId, key.KeyVaultBaseUrl, err)
if key.IsManagedHSM() {
domainSuffix, ok := meta.(*clients.Client).Account.Environment.ManagedHSM.DomainSuffix()
if !ok {
return fmt.Errorf("could not determine Managed HSM domain suffix for environment %q", meta.(*clients.Client).Account.Environment.Name)
}

managedHsmId, err := managedHSMsClient.ManagedHSMIDFromBaseUrl(ctx, diskResourceSubscriptionId, key.KeyVaultBaseURL, domainSuffix)
if err != nil {
return fmt.Errorf("retrieving managed disk Managed HSM at URL %q: %+v", key.KeyVaultBaseURL, err)
}
if managedHsmId == nil {
return fmt.Errorf("retrieving managed disk Managed HSM at URL %q: not found", key.KeyVaultBaseURL)
}
} else {
// make sure the key vault exists
if _, err = keyVaultsClient.KeyVaultIDFromBaseUrl(ctx, diskResourceSubscriptionId, key.KeyVaultBaseURL); err != nil {
return fmt.Errorf("retrieving for managed disk Key Vault at URL %q: %+v", key.KeyVaultBaseURL, err)
}
}

encrypt.Entities.ManagedDisk = &workspaces.ManagedDiskEncryption{
KeySource: workspaces.EncryptionKeySourceMicrosoftPointKeyvault,
KeyVaultProperties: workspaces.ManagedDiskEncryptionKeyVaultProperties{
KeyName: key.Name,
KeyVersion: key.Version,
KeyVaultUri: key.KeyVaultBaseUrl,
KeyVaultUri: key.KeyVaultBaseURL,
},
}
}
Expand All @@ -672,7 +707,7 @@ func resourceDatabricksWorkspaceCreate(d *pluginsdk.ResourceData, meta interface
Sku: &workspaces.Sku{
Name: skuName,
},
Location: location,
Location: location.Normalize(d.Get("location").(string)),
Properties: workspaces.WorkspaceProperties{
PublicNetworkAccess: &publicNetworkAccess,
ManagedResourceGroupId: managedResourceGroupID,
Expand Down Expand Up @@ -875,7 +910,7 @@ func resourceDatabricksWorkspaceRead(d *pluginsdk.ResourceData, meta interface{}
if encryption := model.Properties.Encryption; encryption != nil {
if encryptionProps := encryption.Entities.ManagedServices; encryptionProps != nil {
if encryptionProps.KeyVaultProperties.KeyVaultUri != "" {
key, err := keyVaultParse.NewNestedItemID(encryptionProps.KeyVaultProperties.KeyVaultUri, keyVaultParse.NestedItemTypeKey, encryptionProps.KeyVaultProperties.KeyName, encryptionProps.KeyVaultProperties.KeyVersion)
key, err := keyvault.NewNestedItemID(encryptionProps.KeyVaultProperties.KeyVaultUri, keyvault.NestedItemTypeKey, encryptionProps.KeyVaultProperties.KeyName, encryptionProps.KeyVaultProperties.KeyVersion)
if err == nil {
servicesKeyId = key.ID()
}
Expand All @@ -888,7 +923,7 @@ func resourceDatabricksWorkspaceRead(d *pluginsdk.ResourceData, meta interface{}
if encryption := model.Properties.Encryption; encryption != nil {
if encryptionProps := encryption.Entities.ManagedDisk; encryptionProps != nil {
if encryptionProps.KeyVaultProperties.KeyVaultUri != "" {
key, err := keyVaultParse.NewNestedItemID(encryptionProps.KeyVaultProperties.KeyVaultUri, keyVaultParse.NestedItemTypeKey, encryptionProps.KeyVaultProperties.KeyName, encryptionProps.KeyVaultProperties.KeyVersion)
key, err := keyvault.NewNestedItemID(encryptionProps.KeyVaultProperties.KeyVaultUri, keyvault.NestedItemTypeKey, encryptionProps.KeyVaultProperties.KeyName, encryptionProps.KeyVaultProperties.KeyVersion)
if err == nil {
diskKeyId = key.ID()
}
Expand Down Expand Up @@ -948,6 +983,7 @@ func resourceDatabricksWorkspaceUpdate(d *pluginsdk.ResourceData, meta interface
client := meta.(*clients.Client).DataBricks.WorkspacesClient
acClient := meta.(*clients.Client).DataBricks.AccessConnectorClient
keyVaultsClient := meta.(*clients.Client).KeyVault
managedHSMsClient := meta.(*clients.Client).ManagedHSMs
ctx, cancel := timeouts.ForUpdate(meta.(*clients.Client).StopContext, d)
defer cancel()

Expand Down Expand Up @@ -1178,69 +1214,105 @@ func resourceDatabricksWorkspaceUpdate(d *pluginsdk.ResourceData, meta interface
diskResourceSubscriptionId := commonids.NewSubscriptionID(id.SubscriptionId)

if servicesKeyVaultId != "" {
// If they passed the 'managed_cmk_key_vault_id' parse the Key Vault ID
// to extract the correct key vault subscription for the exists call...
v, err := commonids.ParseKeyVaultID(servicesKeyVaultId)
if err != nil {
return err
}
// If they passed the 'managed_cmk_key_vault_id' parse the Key Vault or Managed HSM ID
// to extract the correct subscription for the exists call...
if v, err := commonids.ParseKeyVaultID(servicesKeyVaultId); err == nil {
servicesResourceSubscriptionId = commonids.NewSubscriptionID(v.SubscriptionId)
} else {
managedHsmId, managedHsmErr := managedhsms.ParseManagedHSMID(servicesKeyVaultId)
if managedHsmErr != nil {
return fmt.Errorf("parsing %q as a Key Vault or Managed HSM ID: %v; %v", servicesKeyVaultId, err, managedHsmErr)
}

servicesResourceSubscriptionId = commonids.NewSubscriptionID(v.SubscriptionId)
servicesResourceSubscriptionId = commonids.NewSubscriptionID(managedHsmId.SubscriptionId)
}
}

if servicesKeyId != "" {
setEncrypt = true
key, err := keyVaultParse.ParseNestedItemID(servicesKeyId)
key, err := keyvault.ParseNestedItemID(servicesKeyId, keyvault.VersionTypeAny, keyvault.NestedItemTypeKey)
if err != nil {
return err
}

// make sure the key vault exists
_, err = keyVaultsClient.KeyVaultIDFromBaseUrl(ctx, servicesResourceSubscriptionId, key.KeyVaultBaseUrl)
if err != nil {
return fmt.Errorf("retrieving the Resource ID for the customer-managed keys for managed services Key Vault in subscription %q at URL %q: %+v", servicesResourceSubscriptionId, key.KeyVaultBaseUrl, err)
if key.IsManagedHSM() {
domainSuffix, ok := meta.(*clients.Client).Account.Environment.ManagedHSM.DomainSuffix()
if !ok {
return fmt.Errorf("could not determine Managed HSM domain suffix for environment %q", meta.(*clients.Client).Account.Environment.Name)
}

managedHsmId, err := managedHSMsClient.ManagedHSMIDFromBaseUrl(ctx, servicesResourceSubscriptionId, key.KeyVaultBaseURL, domainSuffix)
if err != nil {
return fmt.Errorf("retrieving managed services Managed HSM at URL %q: %+v", key.KeyVaultBaseURL, err)
}
if managedHsmId == nil {
return fmt.Errorf("retrieving managed services Managed HSM at URL %q: not found", key.KeyVaultBaseURL)
}
} else {
// make sure the key vault exists
if _, err = keyVaultsClient.KeyVaultIDFromBaseUrl(ctx, servicesResourceSubscriptionId, key.KeyVaultBaseURL); err != nil {
return fmt.Errorf("retrieving managed services Key Vault at URL %q: %+v", key.KeyVaultBaseURL, err)
}
}

encrypt.Entities.ManagedServices = &workspaces.EncryptionV2{
KeySource: workspaces.EncryptionKeySourceMicrosoftPointKeyvault,
KeyVaultProperties: &workspaces.EncryptionV2KeyVaultProperties{
KeyName: key.Name,
KeyVersion: key.Version,
KeyVaultUri: key.KeyVaultBaseUrl,
KeyVaultUri: key.KeyVaultBaseURL,
},
}
}

if diskKeyVaultId != "" {
// If they passed the 'managed_disk_cmk_key_vault_id' parse the Key Vault ID
// to extract the correct key vault subscription for the exists call...
v, err := commonids.ParseKeyVaultID(diskKeyVaultId)
if err != nil {
return err
}
// If they passed the 'managed_disk_cmk_key_vault_id' parse the Key Vault or Managed HSM ID
// to extract the correct subscription for the exists call...
if v, err := commonids.ParseKeyVaultID(diskKeyVaultId); err == nil {
diskResourceSubscriptionId = commonids.NewSubscriptionID(v.SubscriptionId)
} else {
managedHsmId, managedHsmErr := managedhsms.ParseManagedHSMID(diskKeyVaultId)
if managedHsmErr != nil {
return fmt.Errorf("parsing %q as a Key Vault or Managed HSM ID: %v; %v", diskKeyVaultId, err, managedHsmErr)
}

diskResourceSubscriptionId = commonids.NewSubscriptionID(v.SubscriptionId)
diskResourceSubscriptionId = commonids.NewSubscriptionID(managedHsmId.SubscriptionId)
}
}

if diskKeyId != "" {
setEncrypt = true
key, err := keyVaultParse.ParseNestedItemID(diskKeyId)
key, err := keyvault.ParseNestedItemID(diskKeyId, keyvault.VersionTypeAny, keyvault.NestedItemTypeKey)
if err != nil {
return err
}

// make sure the key vault exists
_, err = keyVaultsClient.KeyVaultIDFromBaseUrl(ctx, diskResourceSubscriptionId, key.KeyVaultBaseUrl)
if err != nil {
return fmt.Errorf("retrieving the Resource ID for the customer-managed keys for managed disk Key Vault in subscription %q at URL %q: %+v", diskResourceSubscriptionId, key.KeyVaultBaseUrl, err)
if key.IsManagedHSM() {
domainSuffix, ok := meta.(*clients.Client).Account.Environment.ManagedHSM.DomainSuffix()
if !ok {
return fmt.Errorf("could not determine Managed HSM domain suffix for environment %q", meta.(*clients.Client).Account.Environment.Name)
}

managedHsmId, err := managedHSMsClient.ManagedHSMIDFromBaseUrl(ctx, diskResourceSubscriptionId, key.KeyVaultBaseURL, domainSuffix)
if err != nil {
return fmt.Errorf("retrieving managed disk Managed HSM at URL %q: %+v", key.KeyVaultBaseURL, err)
}
if managedHsmId == nil {
return fmt.Errorf("retrieving managed disk Managed HSM at URL %q: not found", key.KeyVaultBaseURL)
}
} else {
// make sure the key vault exists
if _, err = keyVaultsClient.KeyVaultIDFromBaseUrl(ctx, diskResourceSubscriptionId, key.KeyVaultBaseURL); err != nil {
return fmt.Errorf("retrieving managed disk Key Vault at URL %q: %+v", key.KeyVaultBaseURL, err)
}
}

encrypt.Entities.ManagedDisk = &workspaces.ManagedDiskEncryption{
KeySource: workspaces.EncryptionKeySourceMicrosoftPointKeyvault,
KeyVaultProperties: workspaces.ManagedDiskEncryptionKeyVaultProperties{
KeyName: key.Name,
KeyVersion: key.Version,
KeyVaultUri: key.KeyVaultBaseUrl,
KeyVaultUri: key.KeyVaultBaseURL,
},
}
}
Expand Down
Loading
Loading