How to assign a Azure ML compute instance to a user using python SDK

Question:

How to I assign a compute instance to a user using python SDK?

Right now I’m connecting to my workspace via serviceprincipal authentication using the following code sniped with the python sdk

from azureml.core import Workspace
from azureml.core.authentication import ServicePrincipalAuthentication

svc_pr = ServicePrincipalAuthentication(
    tenant_id="tenant_id_from_my_account",
    service_principal_id="service_principal_id_of_my_app",
    service_principal_password='password_of_my_service_principal')


ws = Workspace(
    subscription_id="my_subscription_id",
    resource_group="my_resource_group",
    workspace_name="my_workspacename",
    auth=svc_pr)

To create a compute instance I’m using this code snipet

from azureml.core.compute import ComputeTarget, ComputeInstance
from azureml.core.compute_target import ComputeTargetException

compute_name = "light-medium-gabriel-2nd"

# Verify that instance does not exist already
try:
    instance = ComputeInstance(workspace=ws, name=compute_name)
    print('Found existing instance, use it.')
except ComputeTargetException:
    compute_config = ComputeInstance.provisioning_configuration(
        vm_size='STANDARD_E4S_V3',
        ssh_public_access=False,
        tags = {'projeto' : 'Data Science','Ambiente':'Homologação'},
    )
    instance = ComputeInstance.create(ws, compute_name, compute_config)
    instance.wait_for_completion(show_output=True)

But I can’t access the compute instance. Since I’m using the service principal autentication it’s like I’m creating the compute instance assigned to the service principal and not to my user?

Asked By: Gabriel Padilha

||

Answers:

I tried in my environment and below results:

You can be able to create compute instance in AzureML workspace with user by using Defaultazurecredential method.

You can follow this MS-DOCS to create compute instance.

Code:

from azure.identity import DefaultAzureCredential
from azure.ai.ml.entities import ComputeInstance
import datetime
from azure.ai.ml import MLClient

subscription_id = "<sub id>"
resource_group = "<resource_grp>"
workspace_name = "wrkspace_name"
credential=DefaultAzureCredential()
ml_client = MLClient(subscription_id,resource_group,workspace_name,credential)
ci_basic_name = "v-vsettu1" + datetime.datetime.now().strftime("%Y%m%d%H%M")
ci_basic = ComputeInstance(name=ci_basic_name,size="STANDARD_DS3_v2")
ml_client.begin_create_or_update(ci_basic).result()

Console:

enter image description here

Also, you can use Cli commands(v2) to create Compute instance.

Command:

az ml compute create -f instance1.yml

yaml

$schema: https://azuremlschemas.azureedge.net/latest/computeInstance.schema.json 
name: v-vsettu1
type: computeinstance
size: STANDARD_DS3_v2

Portal:

enter image description here

Answered By: Venkatesan

First, you need to authenticate to Azure

import os
from azure.ai.ml import exceptions
from azure.identity import DefaultAzureCredential
from azure.identity import InteractiveBrowserCredential

try:
    # NOTE: Using Azure CLI login
    credential: DefaultAzureCredential = DefaultAzureCredential(
                        exclude_cli_credential=False
                        )
    
    credential.get_token("https://management.azure.com/.default",
                         tenant_id=os.environ.get("AZURE_TENANT_ID"))           
except Exception as ex:
    # Fall back to InteractiveBrowserCredential in case DefaultAzureCredential does not work
    # TODO: Add try-except clause for the AZURE_ variables retrieval 
    credential = InteractiveBrowserCredential(
                        tenant_id=os.environ.get("AZURE_TENANT_ID"),
                        login_hint=os.environ.get("AZURE_USERNAME"))
    credential.get_token("https://management.azure.com/.default",
                         tenant_id=os.environ.get("AZURE_TENANT_ID")) 
finally:
    print("Success!")

Second, you need to create your MLClient

from azure.ai.ml import MLClient
from azure.ai.ml.exceptions import ValidationException

# NOTE: We specify a CONFIG_PATH to store the config.json
CONFIG_PATH = "/home/steeve/Git/azureml-examples/.amls/"
try:
    # Load MLClient from a configuration file
    ml_client = MLClient.from_config(credential=credential,
                                               path=CONFIG_PATH,
                                               file_name="config.json")
except ValidationException as ex:
    # NOTE: Update workspace information if not correctly configured
    client_config = {
        "subscription_id": os.environ.get("AZURE_SUBSCRIPTION_ID"),
        "resource_group": os.environ.get("AMLS_RESOURCE_GROUP"),
        "workspace_name": os.environ.get("AMLS_WORKSPACE")}
 
    # Write and reload from config file
    import json

    os.makedirs(name=os.path.dirname(CONFIG_PATH), exist_ok=True)
    with open(file=os.path.join(CONFIG_PATH, "config.json"), mode="w") as file:
        file.write(json.dumps(client_config))

    ml_client = MLClient.from_config(credential=credential, 
                                               path=CONFIG_PATH, 
                                               file_name="config.json")
# Print the ml_client
print(ml_client)

Third, you create a compute instance

import random
from azure.ai.ml.entities import ComputeInstance
from azure.core.exceptions import ResourceNotFoundError
from azure.ai.ml.entities import AssignedUserConfiguration

# NOTE: Refer to AAD to find the user Object ID and Tenant ID
ci_user = AssignedUserConfiguration(                                               
                     user_tenant_id=os.environ.get("AZURE_TENANT_ID"),                                                  
                     user_object_id=os.environ.get("AZURE_USER_ID"))

# Set the random seed
random.seed(a=12)

# NOTE: The pattern is simple: username + some random integer + -ci 
compute_instance_name = f"{os.environ.get('AZURE_USERNAME').split('@')[0]}-{random.randint(a=0, b=1000)}-ci"

# Create compute instance
try:
    compute_instance = ml_client.compute.get(name=compute_instance_name)
    print(f"Found compute instance {compute_instance.name}. Use it.")
except ResourceNotFoundError as e:
    compute_instance = ComputeInstance(
                                name=compute_instance_name, 
                                create_on_behalf_of=ci_user)
                                )

    # Compute instance creation
    print(f"Creating {compute_instance.name}...")
    ml_client.compute.begin_create_or_update(compute=compute_instance)

The Compute Instance will be assigned to the ci_user.

Answered By: numericx