使用适用于 .NET 的 Azure SDK 管理资源

适用于 .NET 的 Azure SDK 管理平面库将帮助你通过 .NET 应用程序创建、预配和管理 Azure 资源。 所有 Azure 服务都有相应的管理库。

借助管理库(命名空间以 Azure.ResourceManager 开头,例如 Azure.ResourceManager.Compute),可以编写配置和部署计划,以执行可通过 Azure 门户、Azure CLI 或其他资源管理工具执行的相同任务。

这些包遵循新的 Azure SDK 准则,其中提供了在所有 Azure SDK 之间共享的核心功能,包括:

  • 直观的 Azure 标识库。
  • 包含自定义策略的 HTTP 管道。
  • 错误处理。
  • 分布式跟踪。

注意

你可能会注意到,某些包仍是预发布版本,其他 Azure 服务管理平面库的阶段性发布正在进行中。 如果正在为特定的 azure 资源寻找稳定版本包,并且目前只有预发布版本可用,请在适用于 .NET 的 Azure SDK 存储库中提出问题

入门

先决条件

安装包

安装适用于 .NET 的 Azure 标识和 Azure 资源管理 NuGet 包。 例如:

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

验证客户端

创建已经过身份验证的客户端的默认选项是使用 DefaultAzureCredential。 由于所有管理 API 都通过同一终结点,因此,若要与资源交互,只需创建一个顶级 ArmClient

若要使用 Azure 进行身份验证并创建一个 ArmClient,请实例化 ArmClient 给定凭据:

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

// Code omitted for brevity

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

有关 Azure.Identity.DefaultAzureCredential 类的详细信息,请参阅 DefaultAzureCredential 类。

管理 SDK 速查表

为开始使用适用于 .NET 的 Azure 管理 SDK,假设有一项创建/列出/更新/删除典型 Azure 服务总线命名空间的任务,请执行以下步骤:

  1. 对要使用的订阅和资源组进行身份验证。
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. 查找用于管理 Azure 资源的相应方法。
操作 方法
获取具有资源标识符的资源 client.GetServiceBusQueueResource(ResourceIdentifier resourceIdentifier)
列出 resourceGroup.GetServiceBusNamespaces()
索引 resourceGroup.GetServiceBusNamespace(string servicebusNamespaceName)
添加/更新 resourceGroup.GetServiceBusNamespaces().CreateOrUpdate(Azure.WaitUntil waitUntil, string name, ServiceBusNamespaceData data)
Contains resourceGroup.GetServiceBusNamespaces().Exists(string servicebusNamespaceName)
删除 client.GetServiceBusQueueResource(ResourceIdentifior resourceIdentifior).Delete()resourceGroup.GetServiceBusNamespace(string servicebusNamespaceName).Delete()

请记住,所有 Azure 资源(包括资源组本身)都可以使用类似于上述示例的代码由相应的管理 SDK 管理。 若要查找正确的 Azure 管理 SDK 包,请查找使用以下模式 Azure.ResourceManager.{ResourceProviderName} 命名的包。

若要了解有关 ResourceIdentifier 的详细信息,请参阅结构化资源标识符

关键概念

理解 Azure 资源层次结构

为了减少执行常见任务所需的客户端数量以及每个客户端所需的冗余参数数量,我们在 SDK 中引入了一个对象层次结构,用于模拟 Azure 中的对象层次结构。 SDK 中的每个资源客户端都有访问其子项的资源客户端的方法,这些客户端的范围已经限定为适当的订阅和资源组。

为此,为 Azure 中的所有资源引入了 3 种标准类型:

{ResourceName}Resource 类

此类型表示一个完整的资源客户端对象,其中包含将详细信息公开为 {ResourceName}Data 类型的 Data 属性。 它还可访问该资源上的所有操作,而无需传入范围参数,如订阅 ID 或资源名称。 这使得直接对列表调用的结果执行操作变得非常方便,因为现在所有内容都作为完整的资源客户端返回。

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);
}

{ResourceName}Data 类

此类型表示构成给定资源的模型。 通常,这是来自服务调用(如 HTTP GET)的响应数据,提供有关基础资源的详细信息。 以前,这由模型类表示。

{ResourceName}Collection 类

此类型表示你可以对属于特定父资源的资源集合执行的操作。 此对象提供大部分逻辑集合操作。

集合行为 集合方法
Iterate/List GetAll()
索引 Get(string name)
添加 CreateOrUpdate(Azure.WaitUntil waitUntil, string name, {ResourceName}Data data)
Contains Exists(string name)

在大多数情况下,资源的父级是资源组,但在某些情况下,资源本身具有子资源,例如子网是虚拟网络的子级。 资源组本身是订阅的子级

汇总

假设公司要求所有虚拟机都添加有所有者标记。 我们的任务是编写一个程序,将标记添加到给定资源组中任何缺少标记的虚拟机。

// 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());
   }
}

结构化资源标识符

资源 ID 包含有关资源本身的有用信息,但它们是必须进行分析的普通字符串。 可使用 ResourceIdentifier 对象进行分析,而不是实现自己的分析逻辑。

示例:使用 ResourceIdentifier 对象分析 ID

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}");

但请记住,其中某些属性可能为 NULL。 通常可以通过资源 ID 字符串本身判断它的类型。 但是,如果不确定,请检查属性是否为 null。

示例:资源标识符生成器

你可能不想从纯 string 手动创建 resourceId。 每个 {ResourceName}Resource 类都有一个静态方法,可以帮助你创建资源标识符字符串。

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

管理现有资源

使用管理客户端库时,对现有资源执行操作是一种常见用例。 在此场景中,通常将要处理的资源的标识符作为字符串。 尽管新对象层次结构适用于在给定父级的范围内进行预配和使用,但在此特定场景下,它并不是最有效的。

下面的示例演示如何访问 AvailabilitySetResource 对象并直接使用其资源标识符对其进行管理:

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);

此方法需要大量代码和三个对 Azure 的 API 调用。 通过利用已在客户端本身之上提供的扩展方法,使用更少的代码且无需任何 API 调用即可完成相同的操作。 利用这些扩展方法,可以传入资源标识符并检索限定范围的资源客户端。 返回的对象是 {ResourceName} 资源。 由于尚未访问 Azure 来检索数据,调用 Data 属性将引发异常,可以使用 HasData 属性来判断资源实例是否包含数据,或者调用资源的 GetGetAsync 方法来检索资源数据。

因此,上一个示例将以与下面类似的内容结束:

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);

检查资源是否存在

如果你不确定要获取的资源是否存在,或者只是想要检查它是否存在,则可使用 Exists()ExistsAsync() 方法,这些方法可从任何 {ResourceName}Collection 类调用。

Exists() 返回 Response<bool>,而 ExistsAsync() 作为其异步版本返回 Task<Response<bool>>。 在 Response<bool> 对象中,可以访问其 Value 属性以检查资源是否存在。 如果资源不存在,则 Valuefalse,反之亦然。

在以前版本的包中,必须捕获 RequestFailedException 并检查 404 状态代码。 利用此新的 API,我们希望这能够提高开发人员的工作效率并优化资源访问。

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.");
}

现在,有了这些便捷的方法,我们只需执行以下操作即可。

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.");
}

示例

创建资源组

// 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;

列出所有资源组

// 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);
}

更新资源组

// 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");

删除资源组

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

有关更详细的示例,请查看我们提供的示例

疑难解答

  • 如果有 bug 要报告或有建议,请通过 GitHub 问题提出问题,并确保向问题添加“预览”标签。
  • 如需帮助,请查看以前的问题,或在 StackOverflow 上使用 Azure 和 .NET 标记提出新问题。
  • 如在身份验证时遇到问题,请参阅 DefaultAzureCredential 文档

后续步骤

更多示例代码

其他文档

如果要从旧 SDK 迁移到此预览版,请查看此迁移指南

有关 Azure SDK 的详细信息,请参阅 Azure SDK 版本