Try the latest Azure SDK for .NET management libraries

Elendil Zheng

The Azure SDK for .NET management libraries have been widely used amongst cloud-native developers. To provide a better experience for managing Azure resources via the Azure SDK for .NET management libraries, the team adopted the idiomatic Azure SDK design guidelines. Now, we’re excited to announce stable versions of the following packages:

Authentication

Authentication is often a pain point to developers. The new Azure SDK for .NET management libraries make it easy for developers to authenticate in the development environment. No code changes are required when deploying the same code to the production environment. With Azure.Identity, you can authenticate an Azure SDK library with a DefaultAzureCredential object. For example:

using Azure.Identity;
using Azure.ResourceManager;

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

DefaultAzureCredential attempts multiple authentication methods in a predefined sequence.

In your local development environment, you can authenticate using Visual Studio. Alternatively, use the Azure CLI to authenticate (az login) before running your application via the .NET CLI. In your test/production environment, in which no user interaction is allowed, you can set environment variables to authenticate your application.

To learn more about authentication, see Authentication in the Azure SDK for .NET.

The core class: ArmClient

You may notice that we’re using the DefaultAzureCredential to create an ArmClient object. The ArmClient object is a key object in the Azure SDK for .NET management libraries. To interact with any Azure resources via the SDK, start with importing that resource’s client library from NuGet. For example, Azure.ResourceManager.Resources, using ArmClient to get the Azure subscription, and finally using the extension method provided by the resource’s client library to manage that resource. The following example creates a new resource group via the new Azure SDK for .NET management libraries:

using Azure;
using Azure.Core;
using Azure.Identity;
using Azure.ResourceManager;
using Azure.ResourceManager.Resources;

const string RESOURCE_GROUP_NAME = "testResourceGroupName";

var client = new ArmClient(new DefaultAzureCredential());
ResourceGroupCollection resourceGroupCollection = 
    client.GetDefaultSubscription().GetResourceGroups();
resourceGroupCollection.CreateOrUpdate(
    WaitUntil.Completed,
    RESOURCE_GROUP_NAME,
    new ResourceGroupData(AzureLocation.WestUS2));

CreateOrUpdate in {ResourceName}Collection

In the preceding sample, a new resource group was created in the default subscription. While we’re creating this new resource group, the SubscriptionResource returned by the GetDefaultSubscription method doesn’t take the responsibility of creating this new resource group. Although by logic, Subscription is the parent of ResourceGroup. Instead, SubscriptionResource calls a method named GetResourceGroups to get a ResourceGroupCollection object. This ResourceGroupCollection extends the IEnumerable interface. That implementation detail allows you to interact with this object like a .NET collection, using LINQ or lambda expressions. For example:

ResourceGroupCollection resourceGroupCollection = 
    client.GetDefaultSubscription().GetResourceGroups();
ResourceGroupResource firstResourceGroupStartWithPrefix = resourceGroupCollection
    .Where(group => group.Data.Name.StartWith("prefix"))
    .FirstOrDefault();

Apart from the preceding sample, some methods have specific names that differ from the traditional LINQ method names.

Collection behavior Container method
Iterate/List GetAll()
Index Get(string name)
Add CreateOrUpdate(WaitUntil waitUntil, string name, {ResourceName}Data data)
Contains Exists(string name)

Through the {ResourceName}Collection class, we’re delegating the capability of managing the resource to the resource’s package itself. The {ResourceName}Collection is always obtained by a call from its parent resource named Get{ResourceName}s/es. Remember:

  • You should import the resource management library before calling the Get{ResourceName}s/es method.
  • A resource management library’s name matches the pattern Azure.ResourceManager.{ResourceProviderName}.

Long-running operation support

Many cloud resource creation tasks take a significant amount of time. For example, creating a new virtual machine. A call of this kind won’t directly return the task execution result through the REST API. Instead, the REST API will return another URL from which you can poll the task execution result through a long-running polling. The Azure SDK for .NET management libraries wrap all of hese steps into something called a long-running operation (LRO). The SDK makes this polling operation transparent to developers. For example, we use the following code to create a new Service Bus namespace resource:

ResourceGroupResource resourceGroup = 
    client.GetDefaultSubscription().GetResourceGroup(resourceGroupName);
ServiceBusNamespaceCollection namespacesCollection = 
    resourceGroup.GetServiceBusNamespaces();
ServiceBusNamespaceResource namespaceResource = 
    namespacesCollection.CreateOrUpdate(
        WaitUntil.Completed, 
        serviceBusName,
        new ServiceBusNamespaceData(AzureLocation.WestUS2)).Value;

The WaitUntil.Completed code indicates that CreateOrUpdate won’t return until the task is complete.

All LROs have an asynchronous method. This approach ensures you don’t block the current thread to wait for Azure to return the final execution result.

Resource identifier

An Azure resource is a hierarchy-based structure. But in some cases, we don’t want to get a resource from its root level. A resource identifier can help us directly locate the desired resource.

Imagine you have a Service Bus queue defined in a Service Bus namespace. That namespace belongs to a resource group. Now you want to delete this Service Bus queue. For example:

using Azure;
using Azure.Identity;
using Azure.ResourceManager;
using Azure.ResourceManager.ServiceBus;

public void DeleteQueueHierarchy(
    string resourceGroupName,
    string servicebusNamespace,
    string queueName)
{
    var client = new ArmClient(new DefaultAzureCredential());
    ResourceGroupResource resourceGroupResource = 
        client.GetDefaultSubscription().GetResourceGroup(resourceGroupName);
    ServiceBusNamespaceResource servicebusNamespaceResource = 
        resourceGroupResource.GetServiceBusNamespace(servicebusNamespace);
    ServiceBusQueueResource queueResource = 
        servicebusNamespaceResource.GetServiceBusQueue(queueName);
    queue.Delete(WaitUntil.Completed);
}

In the preceding sample, you created three objects: ResourceGroupResource, ServiceBusNamespaceResource, and ServiceBusQueueResource. It’s an inefficient way to delete a resource, and unnecessary HTTP calls are made. With the help of ResourceIdentifier, you can delete this Service Bus queue as follows:

using Azure;
using Azure.Identity;
using Azure.ResourceManager;
using Azure.ResourceManager.ServiceBus;

public void DeleteQueue(
    string subscriptionId,
    string resourceGroupName, 
    string serviceBusName,
    string queueName)
{
    var client = new ArmClient(new DefaultAzureCredential());
    ResourceIdentifier resourceIdentifier = 
        ServiceBusQueueResource.CreateResourceIdentifier(
            subscriptionId,
            resourceGroupName,
            serviceBusName,
            queueName);
    ServiceBusQueueResource queue = 
        client.GetServiceBusQueueResource(resourceIdentifier);
    queue.Delete(WaitUntil.Completed);
}

In the preceding sample code, you’re deleting a Service Bus queue with a single HTTP request. Only ServiceBusQueueResource is created in this case. ResourceIdentifier provides a better way for you to get the resource.

Each {ResourceName}Resource class in the Azure SDK for .NET management libraries has a static method named CreateResourceIdentifier. This method can help you generate the resource identifier string. The ArmClient object will contain a corresponding Get{ResourceName}Resource method to directly locate the resource by resource identifier, if you import the corresponding resource’s management library.

Summary

This blog post discussed the new features of the Azure SDK for .NET management libraries. The Azure SDK team will continually release .NET management libraries for other Azure services. If you have any feedback regarding the SDK, open an issue in the Azure SDK for .NET GitHub repository.