Azure Databricks automation databricks-cli authentication issue aad token - databricks

I am trying to create data toolchain in automated way. I am using Azure, databricks-cli.
https://github.com/Azure-Samples/modern-data-warehouse-dataops/blob/main/e2e_samples/parking_sensors/scripts/deploy_infrastructure.sh
I have issue to authenticate to databrics with aad token, generate PAT.
echo "Generate Databricks token"
databricks_host=https://$(echo "$arm_output" | jq -r '.properties.outputs.databricks_output.value.properties.workspaceUrl')
databricks_workspace_resource_id=$(echo "$arm_output" | jq -r '.properties.outputs.databricks_id.value')
databricks_aad_token=$(az account get-access-token --resource 2ff814a6-3304-4ab8-85cb-cd0e6f879c1d --output json | jq -r .accessToken) # Databricks app global id
This is causing me problems.
# Use AAD token to generate PAT token
databricks_token=$(DATABRICKS_TOKEN=$databricks_aad_token \
DATABRICKS_HOST=$databricks_host \
bash -c "databricks tokens create --comment 'deployment'" | jq -r .token_value)
How to authenticate to databricks in order to being able to use databricks cli ??
later I am trying to create secrets but it fails as I am not authenticated.
# Create secret scope
databricks secrets create-scope --scope "$scope_name" \
--scope-backend-type AZURE_KEYVAULT \
--resource-id "$KEYVAULT_RESOURCE_ID" \
--dns-name "$KEYVAULT_DNS_NAME"
Thank you Alex, unfortunately it still does not work on Azure. System:
az login - as subscription owner done
databricks -v
Version 0.16.4
export DATABRICKS_HOST='https://xxx-xxx.16.azuredatabricks.net'
export DATABRICKS_TOKEN=$(az account get-access-token --resource 2ff814a6-3304-4ab8-85cb-cd0e6f879c1d --output json | jq -r .accessToken)
First attempt:
databricks tokens list
Error: b'<html>\n<head>\n<meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>\n<title>Error 403 User not authorized.</title>\n</head>\n<body><h2>HTTP ERROR 403</h2>\n<p>Problem accessing /api/2.0/token/list. Reason:\n<pre> User not authorized.</pre></p>\n</body>\n</html>\n'
Second attempt:
databricks secrets create-scope --scope "XXX" --scope-backend-type AZURE_KEYVAULT --resource-id "$KEYVAULT_RESOURCE_ID" --dns-name "$KEYVAULT_DNS_NAME"
Error: b'<html>\n<head>\n<meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>\n<title>Error 403 User not authorized.</title>\n</head>\n<body><h2>HTTP ERROR 403</h2>\n<p>Problem accessing /api/2.0/secrets/scopes/create. Reason:\n<pre> User not authorized.</pre></p>\n</body>\n</html>\n

You don't need personal access token to create a scope. Just set DATABRICKS_HOST to URL of workspace and DATABRICKS_TOKEN to value of AAD token, and then use databricks secrets create-scope - this command won't work with personal access token. Something like this:
export DATABRICKS_HOST=...
export DATABRICKS_TOKEN=$(az account get-access-token --resource \
2ff814a6-3304-4ab8-85cb-cd0e6f879c1d --output tsv --query accessToken)
databricks secrets create-scope --scope "$scope_name" \
--scope-backend-type AZURE_KEYVAULT \
--resource-id "$KEYVAULT_RESOURCE_ID" \
--dns-name "$KEYVAULT_DNS_NAME"
but please note that this AAD token should be of the real user, not service principal - that's a known limitation:
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. If you're automating things, you can look onto Databricks Terraform Provider that can help with such stuff.

Related

Create Azure Service Principal for Service App using the CLI

I'm trying to create an Azure DevOps service endpoint to connect to Azure Resource Manager and to deploy my app into a App Service.
When I go to Azure DevOps > Project Properties and create a Service Endpoint using the UI (Automated dialog) it works fine and my app can be deployed to App Service from a yaml pipeline, BUT, when I try to replicate it thru the Azure CLI it doesn't work (the build fails to deploy complaining about the Service Principal).
This is my code:
az_account=$(az account show)
az_subscription_id=$(echo $az_account |jq -r '.id')
az_subscription_name=$(echo $az_account |jq -r '.name')
az_tenant_id=$(echo $az_account |jq -r '.tenantId')
az_service_principal=$(az ad sp create-for-rbac -n "my-app-service-principal")
az_service_principal_password=$(echo $az_service_principal|jq -r '.password')
az_service_principal_id=$(az ad sp list --all | jq -c '.[] | select( .appDisplayName | contains("my-app-service-principal"))'| jq -r '.objectId')
export AZURE_DEVOPS_EXT_AZURE_RM_SERVICE_PRINCIPAL_KEY=$az_service_principal_password
az devops service-endpoint azurerm create --azure-rm-service-principal-id $az_service_principal_id --azure-rm-subscription-id $az_subscription_id --azure-rm-subscription-name $az_subscription_name --azure-rm-tenant-id $az_tenant_id --name my-app-service-endpoint
How should I create this Service Enpoint programatically with the Azure CLI?
Updated with the Azure DevOps error:
Your script simply creates the Service Principal but it is not giving any permission to the SP.
I would add some lines like these to create a Resource Group and scope permission to it
az_service_principal_appid = $(echo $az_service_principal|jq -r '.appId')
az group create --name myrg --location westeurope
az role assignment create --role Contributor --assignee $az_service_principal_appid --resource-group myrg
Clearly you need to think how to arrange your resources and SPs: you may need many of both depending on your architecture.

Azure Data Lake Storage Gen2 access token generation - "AADSTS65001: The user or administrator has not consented to use the application with ID

I'm trying to generate access and refresh tokens to be able to sign in to the Azure Data Lake Storage Gen2 using external application with allows OAuth.
What was done:
Created Storage account using https://learn.microsoft.com/en-us/azure/storage/blobs/data-lake-storage-quickstart-create-account
Created Azure AD application using https://learn.microsoft.com/en-us/azure/active-directory/develop/howto-create-service-principal-portal
Granted admin consent to application from the 2nd step - https://i.imgur.com/myMtkeu.png
Also granted admin consent to enterprise apps with name as the app from step 2
https://i.imgur.com/BPX48NE.png
Steps 3 and 4 were done as described here - https://learn.microsoft.com/en-us/azure/active-directory/manage-apps/configure-user-consent#grant-admin-consent-when-registering-an-app-in-the-azure-portal
Then I generated authorization code
https://login.microsoftonline.com/<TENANT ID>/oauth2/v2.0/authorize?client_id=<CLIENT ID>&response_type=code&redirect_uri=https%3A%2F%2Flocalhost%2Fmyapp%2F&response_mode=query&scope=offline_access%20user.read%20mail.read&state=12345
After that I tried to get the token
curl -X POST https://login.microsoftonline.com/<TENANT ID>/oauth2/token \
-F redirect_uri=https://localhost/myapp/ \
-F grant_type=authorization_code \
-F resource=https://management.core.windows.net/ \
-F client_id=<CLIENT ID> \
-F client_secret=<CLIENT SECRET> \
-F code=OAQABAAIAAAAP0wLlqdLVToOpA4kwzSnxLhHJrARX8557... (Authorization code)
As a result received the error below
"error":"invalid_grant","error_description":"AADSTS65001:
The user or administrator has not consented to use the application with ID
'<CLIENT ID>' named '<APP NAME>'. Send an interactive authorization request
for this user and resource.\r\nTrace ID: <TRACE ID>\r\nCorrelation ID:
<CORRELATION ID>\r\nTimestamp: 2019-09-03 13:31:50Z","error_codes":[65001],
"timestamp":"2019-09-03 13:31:50Z","trace_id":"<TRACE ID>",
"correlation_id":"<CORRELATION ID>","suberror":"consent_required"```
You got the authorization code by using V2.0 endpoint, but you used v1.0 when you got the token. And the value of resource is not correct.
Try with below
Get authorization code
https://login.microsoftonline.com/<TENANT ID>/oauth2/authorize?client_id=<CLIENT ID>&response_type=code&redirect_uri=https%3A%2F%2Flocalhost%2Fmyapp%2F&response_mode=query&resource=https://datalake.azure.net/&state=12345
get the token
curl -X POST https://login.microsoftonline.com/<TENANT ID>/oauth2/token \
-F redirect_uri=https://localhost/myapp/ \
-F grant_type=authorization_code \
-F resource=https://datalake.azure.net \
-F client_id=<CLIENT ID> \
-F client_secret=<CLIENT SECRET> \
-F code=OAQABAAIAAAAP0wLlqdLVToOpA4kwzSnxLhHJrARX8557... (Authorization code)

Hot to fix 'authentication required' while trying to delete image tag from Azure Registry?

Ok, I need to delete image with specific tag from Azure Registry(ACR) using Azure CLI and authenticate with service principals.
I have tried already with bash script to first get service principals, then to login to azure with Azure CLI,(and I can see response that I have successfully logged in, with correct subscription id) and then when I try to execute delete command, I'm being asked
This operation will delete the manifest 'sha256:531d60fe70137820c7f9e589' and all the following images: 'sampleImage:1.0.0'.
Are you sure you want to continue? (y/n): y
and when I hit y, I get : Error: authentication required. Correlation ID: ****
Here is the code :
CLIENT_ID = ****
CLIENT_SECRET = ****
TENANT_ID = ****
az login --service-principal -u $CLIENT_ID -p $CLIENT_SECRET -t $TENANT_ID
REGISTRY_NAME="acrregistryname"
az acr login --name $REGISTRY_NAME
# Delete image from ACR
az acr repository delete --name $REGISTRY_NAME --image sampleImage:1.0.0
What I'm missing here?
expected : delete image successully
actual : Authentication required
For your requirement, actually, there are three conditions you need to pay attention to.
Delete the repository. For this requirement, you just need to have the AcrDelete role of the ACR.
Delete the image by the tag. For this requirement, you need to have at least two permission of the ACR: Access Resource Manager(similar to the Read role) and AcrDelete. So the appropriate role with the least permission is the Contributor role, more privilege is Owner. But the security role is Contributor and it's also recommended.
Delete the image by the manifest digest. For this requirement, it's the same situation as the 2.
So, finally, if you want to delete the whole repository, you need the AcrDelete role of the ACR. If you want to delete some data of the repository, you need the Contributor role of the ACR.
When the role is OK. All steps are below:
CLIENT_ID = ****
CLIENT_SECRET = ****
TENANT_ID = ****
REGISTRY_NAME="acrregistryname"
az login --service-principal -u $CLIENT_ID -p $CLIENT_SECRET --tenant $TENANT_ID
az acr login -n $REGISTRY_NAME
You can choose the step below as you need.
# delete the whole repository
az acr repository delete -n $REGISTRY_NAME --repository repository_name
# delete the image by the tag
az acr repository delete -n $REGISTRY_NAME --image imageName:tag
# delete the image by manifest digest
az acr repository delete -n $REGISTRY_NAME --image imageName#xxxxxxxx
What permissions does your service principal have? Note it will need Owner, Contributor or AcrDelete.
https://learn.microsoft.com/en-us/azure/container-registry/container-registry-roles

Adding Azure account fails in Halyard. Azure subscription is not recognized

I am trying to deploy Spinnaker to a K8s cluster using Halyard running on an Ubuntu 16.04 VM. The Kubernetes cluster is deployed on Azure Kubernetes Service.
I am following the instructions here to add an Azure account to Halyard: https://www.spinnaker.io/setup/install/providers/azure/
I get the error in the last steps.
hal config provider azure account add my-azure-account --client-id $APP_ID --tenant-id $TENANT_ID --subscription-id $SUBSCRIPTION_ID --default-key-vault $VAULT_NAME --default-resource-group $RESOURCE_GROUP --app-key
The appKey (password) of your service principal.:
Get current deployment
Success
Add the my-azure-account account
Failure Problems in default.provider.azure: ! ERROR Error
instantiating Azure credentials: The subscription ‘XXX-XX-X-XXXXXX’
could not be found. ? Follow instructions here
https://aka.ms/azspinconfig to setup azure credentials.
Failed to add account my-azure-account for provider azure.
Has anyone successfully deployed Spinnaker on Azure using Halyard?
I see the following errors in halyard.log:
Failure Problems in default.provider.azure: ! ERROR Error
instantiating Azure credentials: The subscription ‘XXX-XX-X-XXXXXX’
could not be found.
Kindly verify the subscription ID which you are passing in Azure account.
First, make sure the provider is enabled:
hal config provider azure enable
Next, run the following hal command to add an account named my-azure-account to your list of Azure accounts:
hal config provider azure account add my-azure-account \
--client-id $APP_ID \
--tenant-id $TENANT_ID \
--subscription-id $SUBSCRIPTION_ID \
--default-key-vault $VAULT_NAME \
--default-resource-group $RESOURCE_GROUP \
--app-key

Azure function app create

I´m using az functionapp create for creating function ap in Azure, where apparts of creating the function app it also hooks it to a bitbucket repo. I´m using parametere --deployment-source-url -u but it seems is not working this way and is giving me an error. This is done by a jenkin file pipeline
node {
stage('Azure Login') {
withCredentials([azureServicePrincipal('6-8afd-ae40e9cf1e74')]) {
sh 'az login --service-principal -u $AZURE_CLIENT_ID -p $AZURE_CLIENT_SECRET -t $AZURE_TENANT_ID'
sh 'az account set -s $AZURE_SUBSCRIPTION_ID'
}
}
stage('Build Azure FuntionApp') {
sh 'az functionapp create -g $RG_NAME -p $SP_NAME -n grey-$JOB_NAME-$BUILD_NUMBER -s $SA_NAME --deployment-source-url https:// bitbucket.org/xxxx/functions/s***strong text***rc/develop --debug'
}
If I put --deployment-source-url -u https://user#bitbucket.org I get:
ERROR: az functionapp create: error: argument
--deployment-source-url/-u: expected one argument
I tried without the -u just : --deployment-source-url https://#bitbucket.org
and the job gets done, but the link with bitbucket repos is not made. Getting this:
So how is it that this work? how come if I put user it says invalid argument and if I don´t it pases but It can find user. Does anyone ever used this command to create a function app? thanks!
If you want to create azure function via azure-cli, you could change the deployment resource url after --deployment-source-url. You could refer to my command to create a function with a blob trigger, replace the url of yours. It works fine on my side.
Note: The Access level should be public, you could check it in Settings like the screenshot below.
az functionapp create --deployment-source-url https://bitbucket.org/xxx/azure-function --resource-group resourcegroupname --consumption-plan-location westeurope --name joyfun22 --storage-account <storage_name>
Besides, you also can use a github repository to create a function.
For example, to use the command below to create a function with a blob trigger.
az functionapp create --deployment-source-url https://github.com/Joyw1/Azure-Function-Trigger --resource-group myResourceGroup --consumption-plan-location westeurope --name <app_name> --storage-account <storage_name>
Update:
If your Access level is private. You need a access token to access your bitbucket repository. Please follow the steps bellow.
1.Go to the Bitbucket Labs -> Access Management -> OAuth -> Add consumer
More details, refer to this link.
2.Enable authenticated git deployment with Azure CLI
#!/bin/bash
gitrepo=<Replace with your GitHub repo URL e.g. https://github.com/Azure-Samples/functions-quickstart.git>
token=<Replace with a GitHub access token>
# Enable authenticated git deployment
az functionapp deployment source update-token \
--git-token $token
For complete command, refer to this link.

Resources