다음을 통해 공유


.NET용 Azure SDK를 사용한 리소스 관리

.NET용 Azure SDK 관리 평면 라이브러리는 .NET 애플리케이션 내에서 Azure 리소스를 만들고, 프로비전하고, 관리하는 데 도움이 됩니다. 모든 Azure 서비스에는 해당 관리 라이브러리가 있습니다.

관리 라이브러리(Azure.ResourceManager(예: Azure.ResourceManager.Compute)로 시작하는 네임스페이스를 사용하여 구성 및 배포 프로그램을 작성하여 Azure Portal, Azure CLI 또는 기타 리소스 관리 도구를 통해 수행할 수 있는 동일한 작업을 수행할 수 있습니다.

이러한 패키지는 다음을 포함하여 모든 Azure SDK 간에 공유되는 핵심 기능을 제공하는 새 Azure SDK 지침따릅니다.

  • 직관적인 Azure ID 라이브러리입니다.
  • 사용자 지정 정책이 있는 HTTP 파이프라인입니다.
  • 오류 처리.
  • 분산 추적.

메모

일부 패키지는 여전히 시험판 버전인 것을 알 수 있습니다. 추가 Azure 서비스의 관리 평면 라이브러리의 단계별 릴리스가 진행 중입니다. 특정 Azure 리소스에 대해 안정적인 버전 패키지를 찾고 있으며 현재 시험판 버전만 사용할 수 있는 경우 Azure SDK for .NET GitHub 리포지토리문제를 제기하세요.

시작

필수 구성 요소

패키지 설치

.NET용 Azure ID 및 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 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에서 관리할 수 있습니다. 올바른 Azure 관리 SDK 패키지를 찾으려면 Azure.ResourceManager.{ResourceProviderName}다음 패턴으로 명명된 패키지를 찾습니다.

ResourceIdentifier에 대한 자세한 내용은 구조적 리소스 식별자참조하세요.

주요 개념

Azure 리소스 계층 구조 이해

공통 작업을 수행하는 데 필요한 클라이언트 수와 각 클라이언트가 수행하는 중복 매개 변수 수를 줄이기 위해 Azure의 개체 계층 구조를 모방하는 개체 계층 구조를 SDK에 도입했습니다. SDK의 각 리소스 클라이언트에는 이미 적절한 구독 및 리소스 그룹으로 범위가 지정된 자식의 리소스 클라이언트에 액세스하는 메서드가 있습니다.

이를 위해 Azure의 모든 리소스에 대해 다음 세 가지 표준 형식을 도입합니다.

{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과 같은 서비스 호출의 응답 데이터이며 기본 리소스에 대한 세부 정보를 제공합니다. 이전에는 Model 클래스로 표현되었습니다.

{ResourceName}Collection 클래스

이 형식은 특정 부모 리소스에 속하는 리소스 컬렉션에서 수행할 수 있는 작업을 나타냅니다. 이 개체는 대부분의 논리 컬렉션 작업을 제공합니다.

컬렉션 동작 수집 방법
반복/목록 GetAll()
색인 가져오기(string name)
더하다 CreateOrUpdate(Azure.WaitUntil waitUntil, 문자열 이름, {ResourceName}Data data)
포함 Exists(string name)

일반적으로 리소스의 부모는 ResourceGroup입니다. 그러나 어떤 경우에는 리소스 자체에 하위 리소스가 있을 수 있습니다. 예를 들어, 서브넷가상 네트워크의 하위 리소스입니다. 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());
   }
}

구조적 리소스 식별자

리소스 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 문자열 자체에서 리소스 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}Resource. 아직 데이터를 검색하기 위해 Azure에 도달하지 않았으므로 Data 속성을 호출하면 예외가 throw되므로 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);

리소스가 있는지 확인

가져올 리소스가 있는지 확실하지 않거나 리소스가 있는지 확인하려는 경우 {ResourceName}Collection 클래스에서 호출할 수 있는 Exists() 또는 ExistsAsync() 메서드를 사용할 수 있습니다.

Exists() 비동기 버전으로 ExistsAsync()Task<Response<bool>>반환하는 동안 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();

자세한 예제를 보려면 사용 가능한 샘플을 살펴보세요.

문제 해결

  • 보고하거나 제안할 버그가 있는 경우 GitHub 문제를 통해 문제를 제출하고 문제에 "미리 보기" 레이블을 추가해야 합니다.
  • 도움이 필요한 경우 이전 질문을 확인하거나 Azure 및 .NET 태그를 사용하여 StackOverflow에서 새 질문을 합니다.
  • 인증에 문제가 있는 경우 DefaultAzureCredential 설명서참조하세요.

다음 단계

추가 샘플 코드

추가 설명서

이전 SDK에서 이 미리 보기로 마이그레이션하는 경우 이 마이그레이션 가이드확인하세요.

Azure SDK에 대한 자세한 내용은 Azure SDK 릴리스 참조하세요.