Il modello a oggetti v2 di Azure Machine Learning separa in modo netto due categorie: le risorse — workspace, compute, datastore — che sono infrastruttura, e gli asset — data, environment, component, model — che sono ciò che il team produce, versiona e riusa. La distinzione non è terminologica: gli asset hanno nome e versione, si referenziano come azureml:nome:versione, si registrano da CLI v2 e SDK v2, e sono l’unità che si promuove da un ambiente all’altro. Chi passa dalla data science all’MLOps scopre proprio qui che «il modello funziona» non basta: deve essere ricostruibile da input dichiarati.

Data asset: tre tipi che non sono intercambiabili

I tipi sono tre e rispondono a scenari diversi. uri_file punta a un singolo file di qualunque formato. uri_folder punta a una cartella: è la scelta per leggere un insieme di CSV o Parquet, o dati non strutturati come immagini e audio. mltable punta a una tabella descritta da un file MLTable che contiene percorsi e trasformazioni di lettura: serve con schemi complessi o mutevoli, per un sottoinsieme di dati tabellari grandi, per AutoML su tabelle e quando i dati sono sparsi su più posizioni di storage.

Il path accetta un percorso locale (che viene caricato automaticamente sul datastore di default), un percorso su datastore nella forma azureml://datastores/<nome>/paths/<path>, un URL https pubblico, oppure uno schema di storage diretto: wasbs:// per Blob e abfss:// per ADLS Gen2.

# data.yml
$schema: https://azuremlschemas.azureedge.net/latest/data.schema.json
type: uri_folder
name: clienti_gold
version: "2026.08"
path: azureml://datastores/gold_layer/paths/clienti/
tags:
  sensitivity: PII

Il fatto più importante è che una versione di data asset è immutabile e la cancellazione non è supportata per scelta di progetto: cancellare un asset farebbe fallire i job che lo consumano, spezzerebbe la lineage e renderebbe l’esperimento irriproducibile. Le vie d’uscita sono due: se il nome è sbagliato o l’asset non serve più lo archivi con az ml data archive, e resta referenziabile ma sparisce dagli elenchi; se il percorso è sbagliato crei una nuova versione con lo stesso nome. Il tipo non si cambia fra versioni: archivi e ricrei con un altro nome. Un asset può nascere anche dall’output di un job dandogli un name: è il modo pulito di far registrare i dati alla pipeline, non a una persona.

Environment: la riproducibilità dell’ambiente di esecuzione

Un environment descrive pacchetti Python e impostazioni software di training e scoring, ed è versionato dal workspace. Le categorie sono tre: curated, forniti da Azure Machine Learning e disponibili di default perché ospitati nel registry azureml di Microsoft; user-managed, dove porti tu il container o un Docker build context; system-managed, dove conda materializza l’ambiente da una specifica sopra un’immagine di base.

Il meccanismo da capire è build, cache e riuso. Alla prima sottomissione, Azure Machine Learning costruisce un’immagine Docker e la mette in cache nel container registry del workspace. Per decidere se riusare la cache calcola un hash su tre elementi: immagine di base, passi Docker custom e pacchetti Python. Nome e versione dell’environment non entrano nell’hash: rinominare non forza una ricostruzione, mentre aggiungere un pacchetto, cambiarne la versione o anche solo riordinare dipendenze e canali sì.

Due trappole ricorrenti. Se dichiari una dipendenza non fissata, per esempio numpy senza versione, l’ambiente resta congelato alla versione disponibile al momento della creazione, e ogni definizione identica riuserà quella: per aggiornare devi fissare la versione e forzare la rebuild. E sull’image patching: Microsoft aggiorna le immagini di base per le vulnerabilità note, con rilasci ogni due settimane, tag immutabili nuovi e :latest che si sposta — ma le patch non arrivano da sole ai tuoi asset. Un managed online endpoint va ridistribuito per prendere l’immagine corretta. I prefissi AzureML- e Microsoft sono riservati ai curated: qualunque modifica locale a un curated produce di fatto un environment custom con un altro nome.

Componenti e registri: riuso dentro, promozione fuori

Un component è un pezzo di codice autonomo che esegue un passo di una pipeline, analogo a una funzione. Ha tre parti: metadata (name, display_name, version, type), interface (input e output tipizzati, con descrizione e default) e infine command, code ed environment che lo eseguono. Essendo interfacciato e versionato, si condivide fra pipeline, workspace e sottoscrizioni, e — dettaglio che l’esame apprezza — è unit-testabile come una funzione qualsiasi.

az ml component create --file prep.yml
az ml component list --name prep_data

Il registry è il pezzo che rende possibile l’MLOps multi-ambiente: disaccoppia gli asset dai workspace e li ospita in una posizione centrale, accessibile a tutti i workspace dell’organizzazione. Ospita modelli, environment, componenti e data asset. Serve quando dev, test e produzione stanno in workspace, sottoscrizioni o region diverse. Il flusso è: sviluppi il modello nel workspace di sviluppo, pubblichi il candidato nel registry, poi lo distribuisci a endpoint in workspace diversi mantenendo la tracciabilità verso il job che lo ha addestrato. Per le pipeline vale l’inverso: registri componenti ed environment nel registry, e quando sottometti il job sono il compute e i dati di training — unici per ogni workspace — a determinare dove gira.

Alla creazione, un registry ha una region primaria e può averne di aggiuntive per la replica, e l’accesso si distribuisce su tre livelli: chi usa gli asset, chi li crea e li usa, chi crea e gestisce i registry stessi. Il ruolo AzureML Registry User permette di leggere, scrivere ed eliminare asset dentro un registry, ma non di creare o eliminare il registry: per quello servono Contributor o Owner.

Da ricordare per l esame

  • uri_file, uri_folder e mltable non sono intercambiabili: mltable per schemi complessi o mutevoli, AutoML su tabelle e dati sparsi su più posizioni.
  • Una versione di data asset è immutabile e non si cancella: si archivia, o si crea una nuova versione con lo stesso nome.
  • L’hash che decide il riuso di un’immagine dipende da immagine di base, passi Docker e pacchetti Python, non da nome e versione dell’environment.
  • Le patch delle immagini di base non si applicano da sole: un online endpoint va ridistribuito.
  • Il registry disaccoppia gli asset dai workspace ed è la via per promuovere modelli e componenti fra ambienti, sottoscrizioni e region.