Gestione delle risorse con Azure SDK per .NET

Le librerie del piano di gestione di Azure SDK per .NET consentono di creare, effettuare il provisioning e gestire le risorse di Azure dalle applicazioni .NET. Per tutti i servizi di Azure sono disponibili librerie di gestione corrispondenti.

Con le librerie di gestione (spazi dei nomi che iniziano con Azure.ResourceManager, ad esempio, Azure.ResourceManager.Compute), è possibile scrivere programmi di configurazione e distribuzione per eseguire le stesse attività che è possibile eseguire tramite il portale di Azure, l'interfaccia della riga di comando di Azure o altri strumenti di gestione delle risorse.

Questi pacchetti seguono le nuove linee guida di Azure SDK, che forniscono funzionalità di base condivise tra tutti gli SDK di Azure, tra cui:

  • Libreria intuitiva di identità di Azure.
  • Una pipeline HTTP con criteri personalizzati.
  • Gestione degli errori.
  • Traccia distribuita.

Nota

È possibile notare che alcuni pacchetti sono ancora versioni non definitive, le versioni in più fasi delle librerie del piano di gestione dei servizi di Azure aggiuntive sono in corso. Se si sta cercando un pacchetto di versione stabile per una determinata risorsa di Azure e attualmente è disponibile solo una versione non definitiva, generare un problema nel repository GitHub di Azure SDK per .NET

Operazioni preliminari

Prerequisiti

Installare il pacchetto

Installare i pacchetti NuGet di Gestione risorse di Azure e Identity di Azure per .NET. Ad esempio:

Install-Package Azure.Identity
Install-Package Azure.ResourceManager
Install-Package Azure.ResourceManager.Resources
Install-Package Azure.ResourceManager.Compute
Install-Package Azure.ResourceManager.Network

Autenticare il client

L'opzione predefinita per creare un client autenticato consiste nell'usare DefaultAzureCredential. Poiché tutte le API di gestione passano attraverso lo stesso endpoint, per interagire con le risorse, è necessario creare un solo ArmClient di livello superiore .

Per eseguire l'autenticazione con Azure e creare ArmClient, creare un'istanza di ArmClient con le credenziali specificate:

using Azure.Identity;
using Azure.ResourceManager;
using System;
using System.Threading.Tasks;

// Code omitted for brevity

ArmClient client = new ArmClient(new DefaultAzureCredential());

Per altre informazioni sulla classe Azure.Identity.DefaultAzureCredential, vedere DefaultAzureCredential Class.

Foglio informativo di Management SDK

Per iniziare a usare Azure Management SDK per .NET, immaginando di avere un'attività per creare/elencare/aggiornare/eliminare uno spazio dei nomi tipico del bus di servizio di Azure, seguire questa procedura:

  1. Eseguire l'autenticazione alla sottoscrizione e al gruppo di risorse su cui si vuole lavorare.
using Azure.Identity;
using Azure.ResourceManager;
using Azure.ResourceManager.ServiceBus;

ArmClient client = new ArmClient(new DefaultAzureCredential());
SubscriptionResource subscription = client.GetDefaultSubscription();
ResourceGroupResource resourceGroup =
    client.GetDefaultSubscription().GetResourceGroup(resourceGroupName);
  1. Trovare il metodo corrispondente per gestire la risorsa di Azure.
Operazione Method
Ottenere una risorsa con l'identificatore di risorsa client.GetServiceBusQueueResource(ResourceIdentifier resourceIdentifier)
List resourceGroup.GetServiceBusNamespaces()
Indice resourceGroup.GetServiceBusNamespace(string servicebusNamespaceName)
Aggiungi/Aggiorna resourceGroup.GetServiceBusNamespaces().CreateOrUpdate(Azure.WaitUntil waitUntil, string name, ServiceBusNamespaceData data)
Contiene resourceGroup.GetServiceBusNamespaces().Exists(string servicebusNamespaceName)
Elimina client.GetServiceBusQueueResource(ResourceIdentifior resourceIdentifior).Delete() oppure resourceGroup.GetServiceBusNamespace(string servicebusNamespaceName).Delete()

Tenere presente che tutte le risorse di Azure, incluso il gruppo di risorse stesso, possono essere gestite dall'SDK di gestione corrispondente usando codice simile all'esempio precedente. Per trovare il pacchetto corretto di Azure Management SDK, cercare i pacchetti denominati con il Azure.ResourceManager.{ResourceProviderName} di modello seguente.

Per altre informazioni su ResourceIdentifier, vedere l’identificatore di risorsa strutturato.

Concetti chiave

Informazioni sulla gerarchia delle risorse di Azure

Per ridurre il numero di client necessari per eseguire attività comuni e il numero di parametri ridondanti che ognuno di questi client accetta, è stata introdotta una gerarchia di oggetti nell'SDK che simula la gerarchia di oggetti in Azure. Ogni client di risorse nell'SDK dispone di metodi per accedere ai client di risorse dei relativi elementi figlio che hanno già come ambito la sottoscrizione e il gruppo di risorse appropriati.

A tale scopo, vengono introdotti tre tipi standard per tutte le risorse in Azure:

classe di Risorse{ResourceName}

Questo tipo rappresenta un oggetto client di risorse completo che contiene una proprietà dati che espone i dettagli come tipo di Dati{ResourceName}. Ha anche accesso a tutte le operazioni su tale risorsa senza dover passare parametri di ambito, ad esempio l'ID sottoscrizione o il nome della risorsa. In questo modo è utile eseguire direttamente le operazioni sul risultato delle chiamate all'elenco, poiché tutto viene restituito come client di risorse completo.

ArmClient client = new ArmClient(new DefaultAzureCredential());
string resourceGroupName = "myResourceGroup";
SubscriptionResource subscription = await client.GetDefaultSubscriptionAsync();
ResourceGroupResource resourceGroup = await subscription.GetResourceGroupAsync(resourceGroupName);
await foreach (VirtualMachineResource virtualMachine in resourceGroup.GetVirtualMachinesAsync())
{
    //previously we would have to take the resourceGroupName and the vmName from the vm object
    //and pass those into the powerOff method as well as we would need to execute that on a separate compute client
    await virtualMachine.PowerOffAsync(WaitUntil.Completed);
}

Classe di Dati{ResourceName}

Questo tipo rappresenta il modello che costituisce una determinata risorsa. In genere, si tratta dei dati di risposta di una chiamata al servizio, ad esempio HTTP GET, e fornisce informazioni dettagliate sulla risorsa sottostante. In precedenza, questo era rappresentato da una classe modello.

Classe di Raccolta{ResourceName}

Questo tipo rappresenta le operazioni che è possibile eseguire su una raccolta di risorse appartenenti a una risorsa padre specifica. Questo oggetto fornisce la maggior parte delle operazioni di raccolta logiche.

Comportamento della raccolta Metodo di raccolta
Iterazione/elenco GetAll()
Indice Get(string name)
Aggiungi CreateOrUpdate(Azure.WaitUntil waitUntil, nome stringa, {ResourceName}Dati)
Contiene Exists(string name)

Nella maggior parte dei casi, l'elemento padre di una risorsa è ResourceGroup, ma in alcuni casi una risorsa ha una risorsa secondaria, ad esempio un Subnet è figlio di un VirtualNetwork. ResourceGroup è un elemento figlio di una sottoscrizione

Combinazione delle funzionalità

Si supponga che l'azienda richieda che tutte le macchine virtuali siano contrassegnate con il proprietario. È stato richiesto di scrivere un programma per aggiungere il tag alle macchine virtuali mancanti in un determinato gruppo di risorse.

// First we construct our armClient
ArmClient client = new ArmClient(new DefaultAzureCredential());

// Next we get a resource group object
// ResourceGroup is a {ResourceName}Resource object from above
SubscriptionResource subscription = await client.GetDefaultSubscriptionAsync();
ResourceGroupResource resourceGroup =
   await subscription.GetResourceGroupAsync("myRgName");

// Next we get the collection for the virtual machines
// vmCollection is a {ResourceName}Collection object from above
VirtualMachineCollection virtualMachineCollection = await resourceGroup.GetVirtualMachines();

// Next we loop over all vms in the collection
// Each vm is a {ResourceName}Resource object from above
await foreach(VirtualMachineResource virtualMachine in virtualMachineCollection)
{
   // We access the {ResourceName}Data properties from vm.Data
   if(!virtualMachine.Data.Tags.ContainsKey("owner"))
   {
       // We can also access all operations from vm since it is already scoped for us
       await virtualMachine.AddTagAsync("owner", GetOwner());
   }
}

Identificatore di risorsa strutturata

Gli ID risorsa contengono informazioni utili sulla risorsa stessa, ma sono stringhe semplici che devono essere analizzate. Anziché implementare la logica di analisi personalizzata, è possibile usare un oggetto ResourceIdentifier che eseguirà l'analisi.

Esempio: Analisi di un ID tramite un oggetto ResourceIdentifier

string resourceId = "/subscriptions/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/resourceGroups/workshop2021-rg/providers/Microsoft.Network/virtualNetworks/myVnet/subnets/mySubnet";
ResourceIdentifier id = new ResourceIdentifier(resourceId);
Console.WriteLine($"Subscription: {id.SubscriptionId}");
Console.WriteLine($"ResourceGroup: {id.ResourceGroupName}");
Console.WriteLine($"Vnet: {id.Parent.Name}");
Console.WriteLine($"Subnet: {id.Name}");

Tenere tuttavia presente che alcune di queste proprietà potrebbero essere null. In genere è possibile indicare dalla stringa ID stessa quale tipo è un ID risorsa. Tuttavia, se non si è certi, verificare se le proprietà sono Null.

Esempio: Generatore identificatore di risorsa

Potrebbe non essere necessario creare manualmente resourceId da un string puro. Ogni classe {ResourceName}Resource ha un metodo statico che consente di creare la stringa dell'identificatore di risorsa.

ResourceIdentifier resourceId =
    AvailabilitySetResource.CreateResourceIdentifier(
        "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee",
        "resourceGroupName",
        "resourceName");

Gestire le risorse esistenti

L'esecuzione di operazioni sulle risorse già esistenti è un caso d'uso comune quando si usano le librerie client di gestione. In questo scenario si ha in genere l'identificatore della risorsa su cui si vuole lavorare come stringa. Anche se la nuova gerarchia di oggetti è ideale per il provisioning e il funzionamento all'interno dell'ambito di un determinato elemento padre, non è il più efficiente quando si tratta di questo scenario specifico.

Ecco un esempio di come accedere a un oggetto AvailabilitySetResource e gestirlo direttamente con il relativo identificatore di risorsa:

using Azure.Identity;
using Azure.ResourceManager;
using Azure.ResourceManager.Resources;
using Azure.ResourceManager.Compute;
using System;
using System.Threading.Tasks;

// Code omitted for brevity

ResourceIdentifier subscriptionId =
    SubscriptionResource.CreateResourceIdentifier("aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee");

ResourceIdentifier resourceId =
    AvailabilitySetResource.CreateResourceIdentifier(
        subscriptionId.SubscriptionId,
        "resourceGroupName",
        "resourceName");

// We construct a new armClient to work with
ArmClient client = new ArmClient(new DefaultAzureCredential());
// Next we get the specific subscription this resource belongs to
SubscriptionResource subscription = client.GetSubscriptionResource(subscriptionId);
// Next we get the specific resource group this resource belongs to
ResourceGroupResource resourceGroup = await subscription.GetResourceGroupAsync(resourceId.ResourceGroupName);
// Finally we get the resource itself
// Note: for this last step in this example, Azure.ResourceManager.Compute is needed
AvailabilitySetResource availabilitySet = await resourceGroup.GetAvailabilitySetAsync(resourceId.Name);

Questo approccio richiede un sacco di codice e vengono effettuate tre chiamate API in Azure. La stessa operazione può essere eseguita con meno codice e senza chiamate API usando metodi di estensione forniti nel client stesso. Questi metodi di estensione consentono di passare un identificatore di risorsa e recuperare un client di risorse con ambito. L'oggetto restituito è una Risorsa{ResourceName}. Poiché non ha ancora raggiunto Azure per recuperare i dati, la chiamata alla proprietà Data genererà un'eccezione; è possibile usare la proprietà HasData per stabilire se l'istanza della risorsa contiene dati o chiamare il metodo Get o GetAsync sulla risorsa per recuperare i dati della risorsa.

L'esempio precedente dovrebbe quindi essere simile al seguente:

ResourceIdentifier resourceId =
    AvailabilitySetResource.CreateResourceIdentifier(
        "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee",
        "resourceGroupName",
        "resourceName");
// We construct a new armClient to work with
ArmClient client = new ArmClient(new DefaultAzureCredential());
// Next we get the AvailabilitySet resource client from the armClient
// The method takes in a ResourceIdentifier but we can use the implicit cast from string
AvailabilitySetResource availabilitySet = client.GetAvailabilitySetResource(resourceId);
// At this point availabilitySet.Data will be null and trying to access it will throw exception
// If we want to retrieve the objects data we can simply call get
availabilitySet = await availabilitySet.GetAsync();
// we now have the data representing the availabilitySet
Console.WriteLine(availabilitySet.Data.Name);

Controllare se esiste una risorsa

Se non si è certi che esista una risorsa che si vuole ottenere o si vuole solo verificare se esista o meno, è possibile usare metodi Exists() o ExistsAsync(), o che possono essere richiamati da qualsiasi classe {ResourceName}Collection.

Exists() restituisce Response<bool>, mentre ExistsAsync() come versione asincrona restituisce un oggetto Task<Response<bool>>. Nell'oggetto Response<bool> è possibile visitare la relativa proprietà Value per verificare se esiste una risorsa. Value è false se la risorsa non esiste e viceversa.

Nelle versioni precedenti dei pacchetti, è necessario intercettare RequestFailedException ed esaminare il codice di stato per 404. Con questa nuova API, ci auguriamo che questo possa aumentare la produttività degli sviluppatori e ottimizzare l'accesso alle risorse.

ArmClient client = new ArmClient(new DefaultAzureCredential());
SubscriptionResource subscription = await client.GetDefaultSubscriptionAsync();
string resourceGroupName = "myRgName";

try
{
    ResourceGroupResource resourceGroup = await subscription.GetResourceGroupAsync(resourceGroupName);
    // At this point, we are sure that myRG is a not null Resource Group, so we can use this object to perform any operations we want.
}
catch (RequestFailedException ex) when (ex.Status == 404)
{
    Console.WriteLine($"Resource Group {resourceGroupName} does not exist.");
}

Ora con questi metodi pratici, possiamo semplicemente eseguire le operazioni seguenti.

ArmClient client = new ArmClient(new DefaultAzureCredential());
SubscriptionResource subscription = await client.GetDefaultSubscriptionAsync();
string resourceGroupName = "myRgName";

bool exists = await subscription.GetResourceGroups().ExistsAsync(resourceGroupName).Value;

if (exists)
{
    Console.WriteLine($"Resource Group {resourceGroupName} exists.");

    // We can get the resource group now that we know it exists.
    // This does introduce a small race condition where resource group could have been deleted between the check and the get.
    ResourceGroupResource resourceGroup = await subscription.GetResourceGroupAsync(resourceGroupName);
}
else
{
    Console.WriteLine($"Resource Group {rgName} does not exist.");
}

Esempi

Creare un gruppo di risorse

// First, initialize the ArmClient and get the default subscription
ArmClient client = new ArmClient(new DefaultAzureCredential());
// Now we get a ResourceGroup collection for that subscription
SubscriptionResource subscription = await client.GetDefaultSubscriptionAsync();
ResourceGroupCollection resourceGroupCollection = subscription.GetResourceGroups();

// With the collection, we can create a new resource group with an specific name
string resourceGroupName = "myRgName";
AzureLocation location = AzureLocation.WestUS2;
ResourceGroupData resourceGroupData = new ResourceGroupData(location);
ResourceGroupResource resourceGroup = (await resourceGroupCollection.CreateOrUpdateAsync(resourceGroupName, resourceGroupData)).Value;

Elencare tutti i gruppi di risorse

// First, initialize the ArmClient and get the default subscription
ArmClient client = new ArmClient(new DefaultAzureCredential());
SubscriptionResource subscription = await client.GetDefaultSubscriptionAsync();
// Now we get a ResourceGroup collection for that subscription
ResourceGroupCollection resourceGroupCollection = subscription.GetResourceGroups();
// With GetAllAsync(), we can get a list of the resources in the collection
await foreach (ResourceGroupResource resourceGroup in resourceGroupCollection)
{
    Console.WriteLine(resourceGroup.Data.Name);
}

Aggiornare un gruppo di risorse

// Note: Resource group named 'myRgName' should exist for this example to work.
ArmClient client = new ArmClient(new DefaultAzureCredential());
SubscriptionResource subscription = await client.GetDefaultSubscriptionAsync();
string resourceGroupName = "myRgName";
ResourceGroupResource resourceGroup = await subscription.GetResourceGroupAsync(resourceGroupName);
resourceGroup = await resourceGroup.AddTagAsync("key", "value");

Eliminare un gruppo di risorse

ArmClient client = new ArmClient(new DefaultAzureCredential());
SubscriptionResource subscription = await client.GetDefaultSubscriptionAsync();
string resourceGroupName = "myRgName";
ResourceGroupResource resourceGroup = await subscription.GetResourceGroupAsync(resourceGroupName);
await resourceGroup.DeleteAsync();

Per esempi più dettagliati, vedere gli esempi disponibili.

Risoluzione dei problemi

  • Se si dispone di un bug per segnalare o inviare un suggerimento, segnalare un problema tramite problemi di GitHub e assicurarsi di aggiungere l'etichetta "Anteprima" al problema.
  • Per assistenza, controllare le domande precedenti oppure porre nuove domande in StackOverflow usando i tag Di Azure e .NET.
  • In caso di problemi di autenticazione, vedere la documentazione di DefaultAzureCredential.

Passaggi successivi

Altro codice di esempio

Documentazione aggiuntiva

Se si esegue la migrazione dall'SDK precedente a questa anteprima, vedere questa guida alla migrazione.

Per altre informazioni su Azure SDK, vedere Versioni di Azure SDK.