使用適用於 .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 Github 存放庫中提問

開始使用

必要條件

Install the package

安裝適用於 .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)
包含 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 的所有資源導入了三種標準類型:

{ResourceName}Resource 類別

此類型代表完整的資源用戶端物件,所包含的 Data 屬性,會提供 {ResourceName}Data 類型的詳細資料。 其不需要傳入範圍參數 (例如訂閱識別碼或資源名稱),就能存取對該資源執行的所有作業。 現在因為一律會傳回完整的資源用戶端,所以就能直接對列出呼叫的結果執行作業。

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) 的回應資料,可提供基礎資源的詳細資料。 此類型先前由 Model 類別表示。

{ResourceName}Collection 類別

此類型代表您可以對屬於特定父資源之資源集合執行的作業。 此物件提供大部分的邏輯集合作業。

集合行為 收集方法
反覆運算/列出 GetAll()
索引 Get(字串名稱)
CreateOrUpdate(Azure.WaitUntil waitUntil, 字串名稱, {ResourceName}Data data)
包含 Exists(字串名稱)

在大部分情況下,資源的父系是 ResourceGroup,但在某些情況下,資源本身就具有子資源,例如 SubnetVirtualNetwork 的子系。 ResourceGroup 本身是 Subscription 的子系

融會貫通

假設我們公司要求所有虛擬機器都必須標示其擁有者。 我們在撰寫程式時,必須為給定資源群組中遺漏的虛擬機器新增標籤。

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

結構化資源識別碼

資源識別碼本身就包含實用的資源相關資訊,但都是純文字字串,需要加以剖析。 除了實作自己的剖析邏輯之外,您也可以交由 ResourceIdentifier 物件為您執行剖析工作。

範例:使用 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}");

但請注意,其中有一些屬性可能是 null。 一般來說,從識別碼字串本身就能判斷資源識別碼的類型。 若無法確定,可檢查屬性是否為 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}Resource。 因為還未連結 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 問題 (英文) 提問,並請務必為問題加註 “Preview” 標籤。
  • 如果您需要協助,請查看先前的問題,或在 StackOverflow 上使用 Azure 和 .NET 標籤提出新的問題。
  • 驗證問題請參閱 DefaultAzureCredential 文件

下一步

更多範例程式碼

其他文件

若要從舊版 SDK 移轉至此預覽版,請參閱此移轉指南

如需 Azure SDK 的詳細資訊,請參閱 Azure SDK 版本