Reputation: 3693
I am trying to create a key vault backed secret scope in Azure databricks using a powershell script that runs during Azure DevOps deployment. It works fine when I run locally using my own credentials but I get an error when I try to run it using the service principal credentials.
The problem I'm having is similar to but not exactly the same as this previous post.
Here is my script:
[CmdletBinding()]
Param(
$azureADDatabricksAccessToken = $env:AZUREADDATABRICKSACCESSTOKEN,
$azureManagementAccessToken = $env:AZUREMANAGEMENTACCESSTOKEN,
$workspaceResourceId,
$subscription,
$resourceGroup,
$keyVault,
$workspaceUrl,
$scope
)
$headers = @{
"Authorization" = "Bearer $azureADDatabricksAccessToken";
"X-Databricks-Azure-SP-Management-Token" = $azureManagementAccessToken;
"X-Databricks-Azure-Workspace-Resource-Id" = $workspaceResourceId;
}
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
$scopes = (Invoke-RestMethod -Uri "https://$workspaceUrl/api/2.0/secrets/scopes/list" -Method Get -Headers $headers).scopes
$exists = ($scopes | Where-Object {$_.name -eq $scope}).Count -gt 0
if($exists){
Write-Host "Secret scope found";
}
else{
Write-Host "Creating new secret scope";
$body = @{
"scope" = "$scope";
"scope_backend_type" = "AZURE_KEYVAULT";
"backend_azure_keyvault" =
@{
"resource_id" = "/subscriptions/$subscription/resourceGroups/$resourceGroup/providers/Microsoft.KeyVault/vaults/$keyVault";
"dns_name" = "https://$keyVault.vault.azure.net/";
};
"initial_manage_principal" = "users";
}
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
Invoke-RestMethod -Uri "https://$workspaceUrl/api/2.0/secrets/scopes/create" -Method Post -Headers $headers -Body (ConvertTo-Json $body)
}
I get my access tokens like this:
$azureADDatabricksAccessToken = (az account get-access-token --resource 2ff814a6-3304-4ab8-85cb-cd0e6f879c1d --resource-type aad-graph | ConvertFrom-Json).accessToken
$azureManagementAccessToken = (az account get-access-token --resource "https://management.core.windows.net/" | ConvertFrom-Json).accessToken
This works when I log in using az login -t XXXX
but it fails when run as a service principal using az login --service-principal -u XXXX -p XXXX --tenant XXXX
.
The error message I get is:
error_code":"CUSTOMER_UNAUTHORIZED","message":"Unable to grant read/list permission to Databricks service principal to KeyVault
'XXXXX': key not found: https://graph.windows.net/
Is there some other access token header I need to add for graph.windows.net
when running as a service principal?
Upvotes: 2
Views: 2688
Reputation: 19
Assuming you already have a databricks.
You need to get an azure AD token with this command :
az account get-access-token --resource 2ff814a6-3304-4ab8-85cb-cd0e6f879c1d --query "accessToken"
The user who generates the token should be a user inside that databricks.
Be aware, the token expires after around 60 min.
put the generated adtoken, dbrworkspaceUrl, keyVaultName in devops release pipeline variables.
Run the following script :
python -m pip install --upgrade pip setuptools wheel databricks-cli --upgrade
#get kv variables
$keyVaultResp = (Get-AzKeyVault -VaultName '$(keyVaultName)')
$KvResourceId = $keyVaultResp.ResourceId
$KvVaultUri = $keyVaultResp.VaultUri
#set AD token as env variable
$env:DATABRICKS_AAD_TOKEN = "$(adtoken)"
$hostname = "$(dbrworkspaceUrl)"+"/"
Write-Output 'hostname' $hostname $KvResourceId $KvVaultUri
#configure dbr
databricks configure --host $hostname --aad-token
databricks secrets create-scope --scope scope_name --scope-backend-type AZURE_KEYVAULT --resource-id $KvResourceId --dns-name $KvVaultUri --initial-manage-principal users
databricks secrets list-scopes
Configure Databricks CLI service-prin-aad-token
Upvotes: 0
Reputation: 87069
You can't execute this operation using the service principal - this is a limitation on the Azure side. The documentation says about this explicitly:
You need an Azure AD user token to create an Azure Key Vault-backed secret scope with the Databricks CLI. You cannot use an Azure Databricks personal access token or an Azure AD application token that belongs to a service principal.
P.S. It's a big pain point when automating the provisioning of workspaces, but because it's a problem in Azure, everything that you can do is to escalate to their support, maybe it will be prioritized.
P.P.S. have you looked onto Databricks Terraform Provider - it may make your life easier compared to Powershell + REST API
Upvotes: 2