Поделиться через


Управление ресурсами с помощью пакета SDK Azure для .NET

Библиотеки плоскости управления Azure SDK для .NET помогут вам создавать, подготавливать ресурсы Azure и управлять ими из приложений .NET. Все службы Azure имеют соответствующие библиотеки управления.

С помощью библиотек управления (пространства имен, начиная с Azure.ResourceManager, например, Azure.ResourceManager.Compute), можно написать программы конфигурации и развертывания, чтобы выполнять те же задачи, которые можно выполнять с помощью портала Azure, Azure CLI или других средств управления ресурсами.

Эти пакеты соответствуют новым рекомендациям по пакету SDK Azure, предоставляя основные возможности, общие для всех пакетов SDK Azure, включая следующие:

  • Интуитивно понятная библиотека идентификации Azure.
  • Конвейер HTTP с настраиваемыми политиками.
  • Обработка ошибок.
  • Распределенная трассировка.

Заметка

Вы можете заметить, что некоторые пакеты по-прежнему являются предварительной версией. Поэтапные выпуски дополнительных библиотек плоскостей управления служб Azure находятся в процессе. Если вы ищете стабильный пакет версий для определенного ресурса Azure и в настоящее время доступна только предварительная версия, создайте проблему в пакете SDK Azure для репозитория .NET GitHub.

Начало работы

Необходимые условия

  • подписка Azure.
  • Реализация TokenCredential, например, такой тип учетных данных, как в библиотеке удостоверений Azure .

Установка пакета

Установите пакеты NuGet для Azure Identity и управления ресурсами Azure в .NET. Например:

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 для управления системами

Чтобы приступить к работе с пакетом SDK для управления Azure для .NET, представьте, что вам нужно создать, обновить или удалить типичное пространство имен Azure Service Bus. Выполните следующие действия.

  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 для управления с помощью кода, аналогичного приведенному выше примере. Чтобы найти правильный пакет пакета SDK для управления Azure, найдите пакеты с именем со следующим шаблоном 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(string name)
Добавить CreateOrUpdate(Azure.WaitUntil waitUntil, имя строки, {ResourceName}Data)
Содержит Существует(строковое имя)

В большинстве случаев родительским элементом ресурса является ResourceGroup, но в некоторых случаях сам ресурс имеет подресурс, например, подсеть является подресурсом VirtualNetwork. ResourceGroup сам является дочерним элементом подписки

Объединяем все части

Представьте, что наша компания требует, чтобы все виртуальные машины имели метку с именем владельца. Нам поручено написать программу для добавления тега к отсутствующим виртуальным машинам в данной группе ресурсов.

// 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. Обычно по самой строке идентификатора можно определить, к какому типу относится идентификатор ресурса. Но если вы не уверены, проверьте, являются ли свойства нулевыми.

Пример: генератор идентификаторов ресурсов

Возможно, вы не хотите вручную создать resourceId из чистой string. Каждый класс {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);

Этот подход требует большого количества вызовов кода и трех вызовов API в Azure. То же самое можно сделать с меньшим количеством кода и без вызовов API с помощью методов расширения, предоставленных самим клиентом. Эти методы расширения позволяют передавать идентификатор ресурса и извлекать выделенного клиента ресурса. Возвращенный объект является {ResourceName}Resource. Так как он еще не обратился к Azure, чтобы получить данные, вызов свойства Data вызовет исключение, можно использовать свойство HasData для определения того, содержит ли экземпляр ресурса данные или вызывает метод Get или GetAsync на ресурсе для получения данных ресурса.

Таким образом, предыдущий пример будет выглядеть следующим образом:

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, чтобы проверить, существует ли ресурс. Если ресурс не существует, тогда Value — это false, и наоборот.

В предыдущих версиях пакетов необходимо поймать 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();

Для более подробных примеров см. примеры , которые у нас имеются в наличии.

Устранение неполадок

  • Если вы хотите сообщить об ошибке или у вас есть предложение, зарегистрируйте проблему через раздел на GitHub и убедитесь, что вы добавили ярлык "Предварительная версия" к сообщению.
  • Если вам нужна помощь, ознакомьтесь с предыдущими вопросамиили задайте новые на StackOverflow, используя теги Azure и .NET.
  • Если возникли проблемы с проверкой подлинности, ознакомьтесь с документацией по DefaultAzureCredential.

Дальнейшие действия

Дополнительные примеры кода

Дополнительная документация

Если вы переносите старый пакет SDK на эту предварительную версию, ознакомьтесь с этим руководством по миграции .

Дополнительные сведения о пакете SDK для Azure см. в разделе Выпуски Azure SDK.