Accéder aux ressources Azure à partir d’un point de terminaison en ligne avec une identité managée

S’APPLIQUE À :Extension Azure ML CLI v2 (actuelle)Kit de développement logiciel (SDK) Python azure-ai-ml v2 (préversion)

Découvrez comment accéder aux ressources Azure à partir de votre script de scoring avec un point de terminaison en ligne, ainsi qu’avec une identité managée affectée par le système ou une identité managée affectée par l’utilisateur.

Les points de terminaison gérés et les points de terminaison Kubernetes permettent à Azure Machine Learning de gérer le travail d’approvisionnement de votre ressource de calcul et le déploiement de votre modèle Machine Learning. En général, votre modèle doit accéder aux ressources Azure, comme Azure Container Registry ou votre stockage blob pour l’inférence ; avec une identité managée, vous pouvez accéder à ces ressources sans avoir à gérer les informations d’identification dans votre code. En savoir plus sur les Identités managées.

Ce guide part du principe que vous ne disposez pas d’une identité managée, d’un compte de stockage, ni d’un point de terminaison en ligne. Si vous disposez déjà de ces composants, passez à la section Accorder l’autorisation d’accès à l’identité managée.

Prérequis

  • Pour utiliser Azure Machine Learning, vous devez disposer d’un abonnement Azure. Si vous n’avez pas d’abonnement Azure, créez un compte gratuit avant de commencer. Essayez la version gratuite ou payante d’Azure Machine Learning dès aujourd’hui.

  • Installez et configurez Azure CLI et l’extension ML (v2). Pour plus d’informations, consultez Installer, configurer et utiliser l’interface CLI 2.0.

  • Un groupe de ressources Azure, où vous (ou le principal de service que vous utilisez) devez avoir l’Administrateur de l’accès utilisateur et l’accès contributeur. Vous disposez d’un tel groupe de ressources si vous avez configuré votre extension ML conformément à l’article précédent.

  • Un espace de travail Azure Machine Learning. Vous disposez déjà d’un espace de travail si vous avez configuré votre extension ML conformément à l’article précédent.

  • Un modèle Machine Learning entraîné prêt pour le scoring et le déploiement. Si vous suivez la procédure décrite dans l’échantillon, un modèle est fourni.

  • Si vous n’avez pas encore défini les paramètres par défaut pour l’interface CLI Azure, enregistrez vos paramètres par défaut. Pour éviter de transmettre plusieurs fois les valeurs de votre abonnement, de votre espace de travail et de votre groupe de ressources, exécutez le code suivant :

    az account set --subscription <subscription ID>
    az configure --defaults gitworkspace=<Azure Machine Learning workspace name> group=<resource group>
    
  • Pour suivre l’échantillon, clonez le référentiel d’échantillons, puis remplacez le répertoire pour cliquer.

    git clone https://github.com/Azure/azureml-examples --depth 1
    cd azureml-examples/cli
    

Limites

  • L’identité d’un point de terminaison est immuable. Durant la création du point de terminaison, vous pouvez l’associer à une identité affectée par le système (par défaut) ou par l’utilisateur. Vous ne pouvez pas modifier l’identité une fois que le point de terminaison a été créé.
  • Si votre Consommation réelle des ressources (ARC) et votre stockage d’objets blob sont configurés comme privés, c’est-à-dire derrière un réseau virtuel, l’accès à partir du point de terminaison Kubernetes doit se faire via la liaison privée, que votre espace de travail soit public ou privé. Pour plus d’informations sur le paramètre de liaison privée, veuillez consulter Comment sécuriser un réseau virtuel d’espace de travail.

Configurer des variables pour le déploiement

Configurez les noms de variables pour l’espace de travail, l’emplacement de l’espace de travail et le point de terminaison que vous souhaitez créer pour les utiliser dans votre déploiement.

Le code suivant exporte ces valeurs en tant que variables d’environnement dans votre point de terminaison :

export WORKSPACE="<WORKSPACE_NAME>"
export LOCATION="<WORKSPACE_LOCATION>"
export ENDPOINT_NAME="<ENDPOINT_NAME>"

Ensuite, spécifiez les noms que vous voulez donner à vos compte Stockage Blob, conteneur d’objets blob et fichier. Ces noms de variables sont définis ici et sont référencés dans les commandes az storage account create et az storage container create dans la section suivante.

Le code suivant exporte ces valeurs en tant que variables d’environnement :

export STORAGE_ACCOUNT_NAME="<BLOB_STORAGE_TO_ACCESS>"
export STORAGE_CONTAINER_NAME="<CONTAINER_TO_ACCESS>"
export FILE_NAME="<FILE_TO_ACCESS>"

Une fois ces variables exportées, créez un fichier texte localement. Lorsque le point de terminaison est déployé, le script de scoring accède à ce fichier texte à l’aide de l’identité managée affectée par le système qui est générée lors de la création du point de terminaison.

Définir la configuration du déploiement

Pour déployer un point de terminaison en ligne avec l’interface CLI, vous devez définir la configuration dans un fichier YAML. Pour plus d’informations sur le schéma YAML, consultez le document Référence YAML sur les points de terminaison en ligne.

Les fichiers YAML dans les exemples suivants sont utilisés pour créer des points de terminaison en ligne.

L’exemple YAML suivant se trouve à endpoints/online/managed/managed-identities/1-sai-create-endpoint. Le fichier,

  • Définit le nom par lequel vous souhaitez faire référence au point de terminaison, my-sai-endpoint.
  • Spécifie le type d’autorisation à utiliser pour accéder au point de terminaison, auth-mode: key.
$schema: https://azuremlschemas.azureedge.net/latest/managedOnlineEndpoint.schema.json
name: my-sai-endpoint
auth_mode: key

Cet exemple YAML, 2-sai-deployment.yml,

  • Spécifie que le type de point de terminaison que vous souhaitez créer est un point de terminaison online.
  • Indique que le point de terminaison est associé à un déploiement nommé blue.
  • Configure les détails du déploiement, tels que le modèle à déployer ainsi que l’environnement et le script de scoring à utiliser.
$schema: https://azuremlschemas.azureedge.net/latest/managedOnlineDeployment.schema.json
name: blue
model:
  path: ../../model-1/model/
code_configuration:
  code: ../../model-1/onlinescoring/
  scoring_script: score_managedidentity.py
environment:
  conda_file: ../../model-1/environment/conda-managedidentity.yaml
  image: mcr.microsoft.com/azureml/openmpi4.1.0-ubuntu20.04:latest
instance_type: Standard_DS3_v2
instance_count: 1
environment_variables:
  STORAGE_ACCOUNT_NAME: "storage_place_holder"
  STORAGE_CONTAINER_NAME: "container_place_holder"
  FILE_NAME: "file_place_holder"

Créer l’identité managée

Pour accéder aux ressources Azure, créez une identité managée affectée par l’utilisateur ou affectée par le système pour votre point de terminaison en ligne.

Quand vous créez un point de terminaison en ligne, une identité managée affectée par le système est générée automatiquement pour vous, il n’est donc pas nécessaire d’en créer une distincte.

Créer un compte de stockage et un conteneur

Pour cet exemple, créez un compte Stockage Blob et un conteneur d’objets blob, puis charger le fichier texte créé auparavant dans le conteneur d’objets blob. Vous donnez au point de terminaison en ligne et à l’identité managée l’accès à ce compte de stockage et à ce conteneur blob.

En premier lieu, créez un compte de stockage.

az storage account create --name $STORAGE_ACCOUNT_NAME --location $LOCATION

Ensuite, créez le conteneur d’objets blob dans le compte de stockage.

az storage container create --account-name $STORAGE_ACCOUNT_NAME --name $STORAGE_CONTAINER_NAME

Chargez alors votre fichier texte dans le conteneur d’objets blob.

az storage blob upload --account-name $STORAGE_ACCOUNT_NAME --container-name $STORAGE_CONTAINER_NAME --name $FILE_NAME --file endpoints/online/managed/managed-identities/hello.txt

Créez un point de terminaison en ligne

Le code suivant crée un point de terminaison en ligne sans spécifier de déploiement.

Avertissement

L’identité d’un point de terminaison est immuable. Durant la création du point de terminaison, vous pouvez l’associer à une identité affectée par le système (par défaut) ou par l’utilisateur. Vous ne pouvez pas modifier l’identité après la création du point de terminaison.

Lorsque vous créez un point de terminaison en ligne, une identité managée affectée par le système est créée par défaut pour le point de terminaison.

az ml online-endpoint create --name $ENDPOINT_NAME -f endpoints/online/managed/managed-identities/1-sai-create-endpoint.yml

Vérifiez l’état du point de terminaison avec les éléments suivants.

az ml online-endpoint show --name $ENDPOINT_NAME

En cas de problème, consultez Résolution des problèmes de déploiement et de scoring de points des terminaison en ligne.

Accorder l’autorisation d’accès à l’identité managée

Important

Les points de terminaison en ligne nécessitent l’autorisation de tirage (pull) Azure Container Registry, l’autorisation AcrPull, sur le registre de conteneurs et l’autorisation Lecteur des données Storage Blob sur le magasin de données par défaut de l’espace de travail.

Vous pouvez permettre au point de terminaison en ligne d’accéder à votre stockage via son identité managée affectée par le système ou permettre à l’identité managée affectée par l’utilisateur d’accéder au compte de stockage créé dans la section précédente.

Récupérez l’identité managée affectée par le système qui a été créée pour votre point de terminaison.

system_identity=`az ml online-endpoint show --name $ENDPOINT_NAME --query "identity.principal_id" -o tsv`

À partir de là, vous pouvez accorder à l’identité managée affectée par le système l’autorisation d’accéder à votre stockage.

az role assignment create --assignee-object-id $system_identity --assignee-principal-type ServicePrincipal --role "Storage Blob Data Reader" --scope $storage_id

Script de scoring pour accéder à la ressource Azure

Reportez-vous au script suivant pour comprendre comment utiliser votre jeton d’identité pour accéder aux ressources Azure. Dans ce scénario, il s’agit du compte de stockage créé dans les sections précédentes.

import os
import logging
import json
import numpy
import joblib
import requests
from azure.identity import ManagedIdentityCredential
from azure.storage.blob import BlobClient


def access_blob_storage_sdk():
    credential = ManagedIdentityCredential(client_id=os.getenv("UAI_CLIENT_ID"))
    storage_account = os.getenv("STORAGE_ACCOUNT_NAME")
    storage_container = os.getenv("STORAGE_CONTAINER_NAME")
    file_name = os.getenv("FILE_NAME")

    blob_client = BlobClient(
        account_url=f"https://{storage_account}.blob.core.windows.net/",
        container_name=storage_container,
        blob_name=file_name,
        credential=credential,
    )
    blob_contents = blob_client.download_blob().content_as_text()
    logging.info(f"Blob contains: {blob_contents}")


def get_token_rest():
    """
    Retrieve an access token via REST.
    """

    access_token = None
    msi_endpoint = os.environ.get("MSI_ENDPOINT", None)
    msi_secret = os.environ.get("MSI_SECRET", None)

    # If UAI_CLIENT_ID is provided then assume that endpoint was created with user assigned identity,
    # # otherwise system assigned identity deployment.
    client_id = os.environ.get("UAI_CLIENT_ID", None)
    if client_id is not None:
        token_url = (
            msi_endpoint + f"?clientid={client_id}&resource=https://storage.azure.com/"
        )
    else:
        token_url = msi_endpoint + f"?resource=https://storage.azure.com/"

    logging.info("Trying to get identity token...")
    headers = {"secret": msi_secret, "Metadata": "true"}
    resp = requests.get(token_url, headers=headers)
    resp.raise_for_status()
    access_token = resp.json()["access_token"]
    logging.info("Retrieved token successfully.")
    return access_token


def access_blob_storage_rest():
    """
    Access a blob via REST.
    """

    logging.info("Trying to access blob storage...")
    storage_account = os.environ.get("STORAGE_ACCOUNT_NAME")
    storage_container = os.environ.get("STORAGE_CONTAINER_NAME")
    file_name = os.environ.get("FILE_NAME")
    logging.info(
        f"storage_account: {storage_account}, container: {storage_container}, filename: {file_name}"
    )
    token = get_token_rest()

    blob_url = f"https://{storage_account}.blob.core.windows.net/{storage_container}/{file_name}?api-version=2019-04-01"
    auth_headers = {
        "Authorization": f"Bearer {token}",
        "x-ms-blob-type": "BlockBlob",
        "x-ms-version": "2019-02-02",
    }
    resp = requests.get(blob_url, headers=auth_headers)
    resp.raise_for_status()
    logging.info(f"Blob contains: {resp.text}")


def init():
    global model
    # AZUREML_MODEL_DIR is an environment variable created during deployment.
    # It is the path to the model folder (./azureml-models/$MODEL_NAME/$VERSION)
    # For multiple models, it points to the folder containing all deployed models (./azureml-models)
    # Please provide your model's folder name if there is one
    model_path = os.path.join(
        os.getenv("AZUREML_MODEL_DIR"), "model/sklearn_regression_model.pkl"
    )
    # deserialize the model file back into a sklearn model
    model = joblib.load(model_path)
    logging.info("Model loaded")

    # Access Azure resource (Blob storage) using system assigned identity token
    access_blob_storage_rest()
    access_blob_storage_sdk()

    logging.info("Init complete")


# note you can pass in multiple rows for scoring
def run(raw_data):
    logging.info("Request received")
    data = json.loads(raw_data)["data"]
    data = numpy.array(data)
    result = model.predict(data)
    logging.info("Request processed")
    return result.tolist()

Créer un déploiement avec votre configuration

Créez un déploiement associé au point de terminaison en ligne. En savoir plus sur le déploiement sur des points de terminaison en ligne.

Avertissement

Ce déploiement peut prendre approximativement entre 8 et 14 minutes selon que l’environnement/l’image sous-jacent est généré pour la première fois ou non. Les déploiements ultérieurs avec le même environnement seront plus rapides.

az ml online-deployment create --endpoint-name $ENDPOINT_NAME --all-traffic --name blue --file endpoints/online/managed/managed-identities/2-sai-deployment.yml --set environment_variables.STORAGE_ACCOUNT_NAME=$STORAGE_ACCOUNT_NAME environment_variables.STORAGE_CONTAINER_NAME=$STORAGE_CONTAINER_NAME environment_variables.FILE_NAME=$FILE_NAME

Notes

La valeur de l’argument --name peut écraser la clé name dans le fichier YAML.

Vérifiez l’état du déploiement.

az ml online-deployment show --endpoint-name $ENDPOINT_NAME --name blue

Pour affiner la requête ci-dessus afin de retourner uniquement des données spécifiques, consultez Interroger la sortie de commande Azure CLI.

Notes

La méthode init du script de scoring lit le fichier à partir de votre compte de stockage à l’aide du jeton d’identité managée affectée par le système.

Pour vérifier la sortie de la méthode init, consultez le journal de déploiement avec le code suivant.

# Check deployment logs to confirm blob storage file contents read operation success.
az ml online-deployment get-logs --endpoint-name $ENDPOINT_NAME --name blue

Une fois votre déploiement effectué, le modèle, l’environnement et le point de terminaison sont inscrits auprès de votre espace de travail Azure Machine Learning.

Tester le point de terminaison

Une fois votre point de terminaison en ligne déployé, testez et confirmez son fonctionnement avec une demande. Les détails de l’inférence varient d’un modèle à l’autre. Pour ce guide, les paramètres de requête JSON se présentent comme suit :

{"data": [
    [1,2,3,4,5,6,7,8,9,10], 
    [10,9,8,7,6,5,4,3,2,1]
]}

Pour appeler votre point de terminaison, exécutez :

az ml online-endpoint invoke --name $ENDPOINT_NAME --request-file endpoints/online/model-1/sample-request.json

Supprimer le point de terminaison et le compte de stockage

Si vous n’envisagez pas de continuer à utiliser le point de terminaison en ligne déployé et le stockage, supprimez-les pour réduire les coûts. Lorsque vous supprimez le point de terminaison, tous ses déploiements associés sont également supprimés.

az ml online-endpoint delete --name $ENDPOINT_NAME --yes
az storage account delete --name $STORAGE_ACCOUNT_NAME --yes