The Azure REST APIs allow us to interact with nearly every type of resource in Azure programmatically. We can create virtual machines, restart a web application, and copy an Azure SQL database using HTTP requests. There's a few choices to make when deciding how to interact with these resource manager APIs, and some potential areas of confusion. In this post and future posts I hope to provide some guidance on how to work with the APIs effectively and avoid some uncertainties.
If you can send HTTP messages, you can interact with the resource manager APIs at a low level. The Azure REST API Reference includes a list of all possible operations categorized by resource. For example, backing up a web site. Each endpoint gives you a URI, the available HTTP methods (GET, PUT, POST, DELETE, PATCH), and a sample request and response. All these HTTP calls need to be authenticated and authorized, a topic for a future post, but the home page describes how to send the correct headers for any request.
These low levels APIs are documented and available to use, but generally you want to write scripts and programs using a slightly higher level of abstraction and only know about the underlying API for reference and debugging.
Fortunately, specifications for all resource manager APIs are available in OpenAPI / Swagger format. You can find these specifications in the azure-rest-api-specs GItHub repository. With a codified spec in hand, we can generate wrappers for the API. Microsoft has already generated wrappers for us in several different languages.
Microsoft provides Azure management libraries that wrap these underlying APIs for a number of popular languages. You can find links on the Microsoft Azure SDKs page. When looking for a management SDK, be sure to select a management SDK instead of a service SDK. A blob storage management SDK is an SDK for creating and configuring a storage account, whereas the service SDK is for reading and writing blobs inside the storage account. A management SDK generally has the name "management" or "arm" in the name (where arm stands for Azure Resource Manager), but the library names are not consistent across different languages. Instead, the names match the conventions for the ecosystem, and Node packages follow a different style than .NET and Java. As an example, the service SDK for storage in Node is azure-storage-node, whereas the management package is azure-arm-storage.
In addition to SDKs, there are command line utilities for managing Azure. PowerShell is one option. In my experience, PowerShell provides the most complete coverage of the management APIs, and over the years I've seen a few operations that you cannot perform in the Azure portal, but can perform with PowerShell.
However, my favorite command line tool is the cross-platform Azure CLI. Not being a regular user of PowerShell, I find the CLI easier to work with and the available commands are easier to discover. That being said, Azure CLI doesn't cover all of Azure, although new features arrive on a regular cadence.
In general, stick with the command line tools if you have quick, simple scripts to run. Some applications, however, require more algorithms, logic, heuristics, and cooperation with other services. For these scenarios, I'd prefer to work with an SDK in a programming language like C#.
Speaking of which ...
If you are a C# developer who wants to manage Azure using C# code, you have the option of going with raw HTTP messages using a class like HttpClient, or using the SDK. Use the SDK. There is enough flexibility in the SDKs to do everything you need, and you don't need to build your own encapsulation of the APIs.
You do need to choose the correct version of the SDKs. If you search the web for examples of managing Azure from C# code, you'll run across NuGet packages with the name Microsoft.WindowsAzure.Management.*. Do not use these packages, they are obsolete. Make sure you are using packages that start with Microsoft.Azure.Management.* (no Windows in the name).
One caveat to these packages is that the classes inside are auto-generated from the OpenAPI specs, so they tend to feel quirky and discoverability can be difficult. I've found using a good code navigation tool like dotPeek allows me to find the model that I want (model classes represent the data returned by a given API endpoint, i.e. a resource in REST terms), and then use "Find References" to see the operations that act on the model resource.
For C#, It's often easier to work with the Fluent .NET management APIs. These fluent management APIs build on top of the underlying management package, but have extension methods tailored for discoverability and readability. For example, Microsoft.Azure.Management.Sql allows you to use the management API from generated .NET code. The Microsoft.Azure.Management.Sql.Fluent package adds discoverability and readability to the code. Note that not all management packages have a fluent counterpart, however, and not all operations might be exposed from the fluent interface.
This post covers some of the options and decision points for working with the Azure Resource Manager API. In future posts we'll see how to write C# code for interacting with the base API and the fluent API. First, however, we'll have to setup a service principal so our code can be authenticated and authorized to execute against our resources.