How to use Azure Management APIs in C# with Azure.Identity
Azure offers a wide range of management APIs to automate a range of actions that can be performed in the Azure portal. These include things like stopping and starting services, service scaling along with many other activities.
In this post, we’ll cover how the management APIs can be used with both the REST API and through one of the many SDK packages.
Authorization
For any remote access, we need to securely provide authorization details. We have many options on how we can provide this authorization. From using the developer’s credentials in the Az Cli or Visual Studio through, to Managed Identities or a client ID/Secret from an Azure App Registration.
Back in 2018, Microsoft documented on their blog how to authenticate with the Azure management API using the Microsoft.IdentityModel.Clients.ActiveDirectory
Nuget Package along with app registrations. As of December 2022 however, this Nuget package is no longer supported and it is recommended to move over to the Azure.Identity
package.
Using the Azure.Identity
NuGet package opens up many new possibilities beyond just app registrations. With Azure Identity we can use an individual credential provider such as VisualStudioCredential
or AzureCliCredential
. This however restricts our code to only working one way and may not work once deployed. The package also provides the DefaultAzureCredential()
class. Using this it will go through the many different providers, in order until one is able to provide a token. These tokens can then be used for a whole range of APIs and SDKs while working with the portal.
SDK Approach
One of the easiest ways to access the management APIs are via the official SDKs. There are in fact multiple SDK NuGet packages for C#, each working with a different section of Azure. These are all detailed in the Azure SDK Git repository
For this example, we are going to create a simple console app that shuts down a virtual machine. The methods needed are part of the compute API and are accessed via the Azure.ResourceManager.Compute
Nuget package.
using Azure.Core;
using Azure.Identity;
using Azure.ResourceManager;
using Azure.ResourceManager.Compute;
var subscriptionId = "5e26f153-b3d6-41a7-a5f3-b59721945d23";
var resourceGroupName = "Demo";
var resourceName = "demo-vm-2023";
var armClient = new ArmClient(new DefaultAzureCredential());
var id = VirtualMachineResource.CreateResourceIdentifier(
subscriptionId,
resourceGroupName,
resourceName);
var result = armClient.GetVirtualMachineResource(new ResourceIdentifier(id));
await result.DeallocateAsync(Azure.WaitUntil.Completed);
Console.WriteLine("Machine shutdown!");
The first action is to build an ArmClient
instance. This uses the Azure credentials as mentioned previously and will manage all of the authentication steps for us.
As you can see from the code next we need to get a resource identification. Helpfully this can be built up using a helper method with different helper methods provided for each resource type.
Finally, we can use the ARM client and its many methods to perform the action we require. In this case, we are going to deallocate a virtual machine. As it is a C# SDK we get full autocomplete along with documented parameters.
As you can see the SDK along with Azure Identity allows us to automate the Azure portal in only a few lines of easy to read code.
Rest API Approach
Although the SDK packages are more convenient, sometimes you may want to make a single API call using an HTTP client or use a preview feature that is not yet covered by the SDKs.
To demonstrate how this works, we will recreate the console application to deallocate a virtual machine but use the Rest APIs directly. The other available Rest API endpoints are extensively documented and cover all actions you see in the Azure portal.
using Azure.Core;
using Azure.Identity;
var subscriptionId = "5e26f153-b3d6-41a7-a5f3-b59721945d23";
var resourceGroupName = "Demo";
var resourceName = "demo-vm-2023";
var credentials = new DefaultAzureCredential();
var tokenResult = await credentials.GetTokenAsync(new TokenRequestContext(new[] { "https://management.azure.com/.default" }), CancellationToken.None);
using var httpClient = new HttpClient
{
BaseAddress = new Uri("https://management.azure.com/subscriptions/")
};
httpClient.DefaultRequestHeaders.Remove("Authorization");
httpClient.DefaultRequestHeaders.Add("Authorization", $"Bearer {tokenResult.Token}");
var Uri = $"{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Compute/virtualMachines/{resourceName}/deallocate?hibernate=false&api-version=2022-11-01";
var response = await httpClient.PostAsync(Uri, null);
if (response.IsSuccessStatusCode)
{
Console.WriteLine("Machine shutdown!");
}
else
{
var content = await response.Content.ReadAsStringAsync();
Console.WriteLine($"Machine shutdown failed: {content}");
}
Once again we can use the DefaultAzureCredentials
however this time we will need to manually obtain and then add the token to the header of the HTTP request. With the token, we can build up a new HTTP client setting the token value.
The URL format is found in the documentation and it’s built up using similar details to the previous example. We finally can make an HTTP post to send the deallocation request. Unlike using the SDK if we want to wait for the action to complete we would need additional code.
The direct access to the API is useful when we cannot use the SDK. With Azure Identity it makes the authrisation simple.
Summary
In this short post, we have looked at how we can access and manage Azure resources using both SDKs and the REST API directly. In both of these, we used the Azure identity Nuget package to provide authorization.
Title Photo by Will Myers on Unsplash