- Article
- 10 minutes to read
Microsoft Azure Resource Manager is the Azure deployment and management service. It provides a layer of management that allows you to create, update, and delete resources in your Azure account.
This library provides resource group and resource management capabilities for Microsoft Azure.
This library follows thenew Azure SDK guidelinesand provides many basic features:
- Supports MSAL.NET, Azure.Identity is out of the box to support MSAL.NET. - Supports [OpenTelemetry] (https://opentelemetry.io/) for distributed tracing. - HTTP pipeline with custom policies. - Better error handling.- Supports uniform telemetry in all languages.
starting
install the package
Install the Microsoft Azure Resource Management Central Library for .NET withNuGetName:
dotnet add package Azure.ResourceManager
previous requirements
you must have oneMicrosoft Azure Subscription.
Configure a form of authentication in Azure with Azure Identity.
(Video) Microsoft Authentication Library (MSAL) for .NETSome options are:
- AcrossLogin da CLI do Azure.
- Acrosseyes studio.
- Contextenvironmental variables.
More information and different approaches to authentication using Azure Identity can be found atthis document.
authenticate client
The default option for creating an authenticated client is to useAzure default credential
. Since all management APIs go through the same endpoint, to interact with resources, just one level higherArmClient
it has to be created.
To authenticate to Azure and create aArmClient
, do the following code:
using System;using System.Threading.Tasks;using Azure.Core;using Azure.Identity;using Azure.ResourceManager;using Azure.ResourceManager.Compute;using Azure.ResourceManager.Resources; // Code omitted for brevityArmClient client = new ArmClient( new CredencialAzurePredeterminada());
More documentation forAzure.Identity.DefaultAzureCredential
class can be found atthis document.
key concepts
Understanding the Azure Resource Hierarchy
To reduce the number of clients needed to perform common tasks and the number of redundant parameters for each of those clients, we've introduced an object hierarchy in the SDK that mimics the object hierarchy in Azure. Each resource client in the SDK has methods for accessing its children's resource clients that are already scoped to the appropriate subscription and resource group.
To achieve this goal, we present three standard types for all resources in Azure:
[Resource]Resource.cs
This class represents a full feature client object that contains aDataproperty exposing the details as a[Feature]Datatype. You also have access to all operations on that resource without having to pass scoped parameters like subscription ID or resource name. This resource class makes it easier to perform operations directly on the result of list calls, as everything is now returned as a full resource client.
Client ArmClient = new ArmClient(new DefaultAzureCredential());string resourceGroupName = "myResourceGroup";SubscriptionResource subscribe = await client.GetDefaultSubscriptionAsync();ResourceGroupCollection resourceGroups = suscripción.GetResourceGroups();ResourceGroupResource resourceGroup = await resourceGroups.GetAsync(resourceGroupName);await foreach (VirtualMachineResource virtualMachine in resourceGroup.GetVirtualMachines()){ //previously, we would have to take the resourceGroupName and vmName from the vm object //and pass them to the powerOff method, just as we would need to run it on a standby compute client virtualMachine.PowerOffAsync(WaitUntil. Completed);}
[Recurso]Data.cs
This class represents the model that composes a given resource. Typically, this class takes the response data from a service call, such as an HTTP GET, and provides details about the underlying resource. Previously, this class was represented by aModelclassroom.
[Resource]Colección.cs
This class represents the operations you can perform on a collection of resources that belong to a specific parent resource. This class provides most of the logical collection operations.
Collection behavior | collection method |
---|---|
Repeat/list | get all() |
Index | Get (string name) |
To add | CreateOrUpdate(string name, [Resource]Data data) |
contains | Exists (string name) |
For most things, the parent will be aresource group. for example, onesub-antiredepositionis the son of avirtual redit is aresource groupis the son of aEnrollment.
putting it all together
Imagine that our company requires all virtual machines to be tagged with owner. We are tasked with writing a program to add the tag to any missing VMs in a given resource pool.
// First we build our client clientArmClient = new ArmClient(new DefaultAzureCredential()); // Then we get a resource group object // ResourceGroupResource is a [Resource] object of aboveSubscriptionResource subscribe = await client.GetDefaultSubscriptionAsync();ResourceGroupCollection resourceGroups = Subscribe.GetResourceGroups();ResourceGroupResource resourceGroup = await resourceGroups.GetAsync("myRgName"); // Then we get the collection for the virtual machines // vmCollection is a [Resource]Collection object aboveVirtualMachineCollection virtualMachines = resourceGroup.GetVirtualMachines( ); // We then loop through all the virtual machines in the collection // Each virtual machine is a [Resource] object of aboveawait foreach (VirtualMachineResource virtualMachine in virtualMachines){ // Access the [Resource]Data properties of vm.Data if ( !virtualMachine .Data.Tags.ContainsKey("owner")) { // We can also access all operations of the vm, as it is already in scope to wait for virtualMachine.AddTagAsync("owner", "tag value"); }}
Structured resource identifier
Resource IDs contain useful information about the resource itself, but they are simple strings that need to be parsed. Instead of implementing your own parsing logic, you can use aresource identifier
object that will do the analysis for you:novo ResourceIdentifer("myid");
.
Example: Parsing an ID using a ResourceIdentifier object
ResourceIdentifier id = new ResourceIdentifier("/subscriptions/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/resourceGroups/workshop2021-rg/providers/Microsoft.Network/virtualNetworks/myVnet/subnets/mySubnet");Console.WriteLine($"Assinatura: {id.SubscriptionId}");Console.WriteLine($"ResourceGroupResource: {id.ResourceGroupName}");Console.WriteLine($"Vnet: {id.Parent.Name}");Console.WriteLine($"Subnet: {id.Nombre}");
Management of existing resources by resource identifier
Performing operations on resources that already exist is a common use case when using the management client libraries. In this scenario, you typically have the identifier of the resource you want to work on as a string. While the new object hierarchy is great for provisioning and working within the scope of a given parent, it's not the most efficient when it comes to this specific scenario.
Here is an example of how you can access aavailability set
object and manage it directly with its ID:
ResourceIdentifier id = new ResourceIdentifier("/subscriptions/aaaaaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/resourceGroups/workshop2021-rg/providers/Microsoft.Compute/availabilitySets/ws2021availSet"); // Create a new client to work with the ArmClient client = new ArmClient(new DefaultAzureCredential()); // Next, we get the collection of subscriptionsSubscriptionCollection Subscribes = client.GetSubscriptions(); // Next, we get the specific subscription this resource belongs to. ); // Then we get the collection of resource groups that this resource belongs to subscriptionResourceGroupCollection resourceGroups = Subscribe.GetResourceGroups();// Then we get the specific resource group that this resource belongs toResourceGroupResource resourceGroup = await resourceGroups.GetAsync(id. ResourceGroupName) ;// Then we get the collection of availability sets that belong to this resource groupAvailabilitySetCollection AvailabilitySets = r esourceGroup.GetAvailabilitySets(); // Finally, we get the resource itself // Note: For this last step in this example, Azure. ResourceManager.ComputeAvailabilitySetResource AvailabilitySet = wait for AvailabilitySets.GetAsync(id.Name);
This approach required a lot of code and three API calls to Azure. The same can be done with less code and without any API calls using extension methods that we make available in the client itself. These extension methods let you pass a resource identifier and retrieve a client of scoped resources. The returned object is a[Resource]mentioned above since it didn't contact Azure to retrieve the data, but the Data property will be null.
So the example above would look like this:
ResourceIdentifier resourceId = new ResourceIdentifier("/subscriptions/aaaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/resourceGroups/workshop2021-rg/providers/Microsoft.Compute/availabilitySets/ws2021availSet"); // Create a new client to work with the ArmClient client = new ArmClient(new DefaultAzureCredential()); // Then we get the client resource AvailabilitySetResource from the client // The method takes a ResourceIdentifier, but we can use implicit conversion of stringAvailabilitySetResource AvailabilitySet = client.GetAvailabilitySetResource(resourceId); // At this point AvailabilitySet .Data will be null and trying to access it will throw // If we want to retrieve the objects' data, we can simply call getavailabilitySet = await AvailabilitySet.GetAsync(); // now we have the data representing AvailabilitySetConsole.WriteLine(availabilityset. Data.Name);
We also give you the option that if you only know the parts that make up theresource identifier
each resource provides a static method for building the entire chain from those parts. The example above would look like this.
string SubscribeId = "aaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee";string resourceGroupName = "workshop2021-rg";string AvailabilitySetName = "ws2021availSet";ResourceIdentifier resourceId = AvailabilitySetResource.CreateResourceIdentifier(subscriptionId, new resourceGroupAvailabilityName/AvailabilitySet); client to work withArmClient client = new ArmClient(new DefaultAzureCredential()); // Then we get the client resource AvailabilitySetResource from the client // The method takes a ResourceIdentifier, but we can use implicit conversion from stringAvailabilitySetResource AvailabilitySet = client.GetAvailabilitySetResource( resourceId );/ / At this point, AvailabilitySet.Data will be null and trying to access it will generate // If we want to retrieve the objects' data, we can simply call getavailabilitySet = await AvailabilitySet.GetAsync(); // now we have the data that represents o AvailabilitySetConsole.WriteLine(availabilitySet.Data.Name);
Check if there is a [Resource]
If you are not sure if there is a resource you want to get or just want to check if it exists, you can useexist()
method, which can be called from any class in the [Resource]Collection.
exist()
yExisteAsync()
give backAnswer<bool>
where bool is false if the specified resource does not exist. Both methods still provide access to the underlying raw response.
Before these methods were introduced, you would have to understand theRequestFailedException
and inspect the status code for 404.
Client ArmClient = new ArmClient(new DefaultAzureCredential());SubscriptionResource subscription = expect client.GetDefaultSubscriptionAsync();ResourceGroupCollection resourceGroups = subscription.GetResourceGroups();string resourceGroupName = "myRgName";try{ ResourceGroupResource resourceGroup = expect resourceGroups.GetAsyncName ; // At this point, we're pretty sure that myRG is not a null resource group, so we can use this object to perform any operation we want.}catch (RequestFailedException ex) when (ex.Status == 404){ Console . WriteLine($"The resource group {resourceGroupName} does not exist.");}
Now, with these convenience methods, we can make the following code.
Client ArmClient = new ArmClient(new DefaultAzureCredential());SubscriptionResource subscription = expect client.GetDefaultSubscriptionAsync();ResourceGroupCollection resourceGroups = subscription.GetResourceGroups();string resourceGroupName = "myRgName";bool exist = expect resourceGroups.ExistsAsync(reGroupName);if (exists){ Console.WriteLine($"The resource group {resourceGroupName} exists."); // We can get the resource group now that we know it exists. // This introduces a small race condition where the resource group may have been removed between checkout and checkout. ResourceGroupResource resourceGroup = await resourceGroups.GetAsync(resourceGroupName);}else{ Console.WriteLine($"Resource group {resourceGroupName} does not exist.");}
examples
Create a resource group
// First initialize the ArmClient and get the default client subscriptionArmClient = new ArmClient(new DefaultAzureCredential()); // Now we get a ResourceGroupResource collection for that subscriptionSubscriptionResource Subscribe = await client.GetDefaultSubscriptionAsync();ResourceGroupCollection resourceGroups = Subscribe.GetResourceGroups( ); // With the collection we can create a new resource group with a specific name string resourceGroupName = "myRgName";AzureLocation location = AzureLocation.WestUS2;ResourceGroupData resourceGroupData = new ResourceGroupData(location);ArmOperation<ResourceGroupResource> operation = await resourceGroups. CreateOrUpdateAsync(WaitUntil.Completed, resourceGroupName, resourceGroupData);ResourceGroupResource resourceGroup = operation.Value;
List all resource groups
// First, initialize the ArmClient and get the default client subscriptionArmClient = new ArmClient(new DefaultAzureCredential());SubscriptionResource subscribe = await client.GetDefaultSubscriptionAsync(); // Now we get a ResourceGroupResource collection for this subscriptionResourceGroupCollection resourceGroups = Subscribe.GetResourceGroups( ) ; // We can then iterate over this collection to get the resources in the collection each expects (ResourceGroupResource resourceGroup in resourceGroups){ Console.WriteLine(resourceGroup.Data.Name);}
Update a resource group
// Nota: O grupo de recursos denominado 'myRgName' deve existir para que este exemplo funcione. Cliente ArmClient = new ArmClient(new DefaultAzureCredential());SubscriptionResource Subscribe = await client.GetDefaultSubscriptionAsync();ResourceGroupCollection resourceGroups = Subscribe.GetResourceGroups();string resourceGroupName = "myRgName";ResourceGroupResource resourceGroup = await resourceGroups.GetAsync(resourceGroupName);resourceGroup = await resourceGroup.AddTagAsync("chave", "valor");
Delete a resource group
ArmClient client = new ArmClient(new DefaultAzureCredential());SubscriptionResource suscripción = await client.GetDefaultSubscriptionAsync();ResourceGroupCollection resourceGroups = suscripción.GetResourceGroups();string resourceGroupName = "myRgName";ResourceGroupResource resourceGroup = await resourceGroups.GetAsync(resourceGroupName);await resourceGroup.DeleteAsync(WaitUntil.Completed);
For more detailed examples, have a look atsampleswe have available
Testes do Azure Resource Manager
To run the test:network test
To run the test with code coverage and automatically generate an html report:teste dotnet /p:CollectCoverage=true /p:CoverletOutputFormat=cobertura
The coverage report will be put on your way regarding the azure-proto-core test at/roof
in html format to view
Reports can also be viewed VS or VsCode with the appropriate viewer plugin
A brief report will also be displayed on the command line when it runs.
run test with single file or test
To run a code coverage test and automatically generate an html report with a single test:teste dotnet /p:CollectCoverage=true /p:CoverletOutputFormat=coverage --filter <teste a ser executado>
Problems solution
- Submit a problem viaGitHub issues.
- To checkprevious questionsor request new ones on Stack Overflow using Azure and .NET tags.
Next steps
More sample code
- Manage resource groups
- Create a virtual network
- .NET Management Library Code Samples
Other documentation
If you're migrating from the old SDK, check this outmigration guide.
For more information about the Microsoft Azure SDK, seethis site.
contributing
For details on how to contribute to this repository, see thecontribution guide.
This project accepts contributions and suggestions. Most contributions require you to accept a Contributor License Agreement (CLA) which states that you have the right to grant us the right to use your contribution. For more details, visithttps://cla.microsoft.com.
When you submit a pull request, a CLA bot will automatically determine if you need to provide a CLA and decorate the PR accordingly (e.g. tag, comment). Follow the instructions provided by the bot. You will only need to do this once for all repositories that use our CLA.
This project adopted theMicrosoft Open Source Code of Conduct. For more information, see theFrequently asked questions about the Code of Conductthe contactopencode@microsoft.comwith any other questions or comments.