Managing Azure from .NET
dotnet azure

This article contains the code needed for using the Azure .NET SDK to manage Azure resources from server applications.
June 2, 2019

To automatically update my podcast site, I'm using Azure Functions and SoundCloud RSS. Besides uploading the files to Azure Storage, I also need to purge the CDN endpoint to refresh it for everyone (the update happens twice a month so it's not a big deal to do the purge every time). This is where the Azure Management SDK comes into play.

Controlling Azure resources from server code can be useful in many automation scenarios. Purging CDN is one example, creating a container instance and deleting it after it's work is done is another. You can spin up new resources, scale up, scale down, download logs, change configurations etc. directly from C# code.

tl;dr

This article contains the code needed for using the Azure .NET SDK to manage Azure resources from server applications.

How to

To be successful you need the ability to register new applications in your tenant's Azure Active Directory.

Service principal

Azure resources will be managed from server side, so there's no particular user's identity assigned and we need to create a service principal and use the client credential flow.

  1. Sign in to the Azure Portal and go to Azure Active Directory.
  2. Select App registrations.
  3. Click + New registration.
  4. Choose a name for your service principal and leave the rest unchanged.
  5. Click Register.
  6. On the Overview page make note of the Application (client) ID value.
  7. Switch to Certificates & secrets.
  8. In the Client secrets sections click + New client secret.
  9. Set description, choose expiration date and confirm by clicking the Add button.
  10. Finally make note of the secret value in the table. It will not be available once you leave this page!

With the service principal registered, it's time to go back to the Resource Group containing the resources we want to manage and assign permissions.

  1. Go to the Resource Group.
  2. Select Access control (IAM).
  3. Go to Role assignments and click + Add.
  4. Choose appropriate role - generally it's a good practice to assign minimum privileges needed to get the job done (for example in case of CDN it's CDN Profile Contributor , they are usually described in the documentation).
  5. Find your service principal, select it and save.

NuGet (SDK)

Install the following NuGet package into the C# project:

Microsoft.Azure.Management.Fluent

Code

First we need to initialize the Azure client. The SDK offers several authentication options, we're using the FromServicePrincipal helper method, which requires three configuration values. All of them are set as environmental variables (application properties in Azure Web Apps).

public static IAzure CreateAzureClient()
{
    string appId = Environment.GetEnvironmentVariable("PrincipalAppId");
    string appSecret = Environment.GetEnvironmentVariable("PrincipalAppSecret");
    string tenantId = Environment.GetEnvironmentVariable("AzureTenantId");

    var credentials = SdkContext.AzureCredentialsFactory.FromServicePrincipal(appId, appSecret, tenantId, AzureEnvironment.AzureGlobalCloud);

    var azure = Azure
        .Configure()
        .Authenticate(credentials)
        .WithDefaultSubscription();

    return azure;
}

How to get required values?

Now it should be ready to use. It's a "fluent" interface which means that we can chain configurations and commands after each other.

Example 1 - Create a Container Instance with 2 CPUs and 3.5 GB of RAM with a specific Docker container:

Required role: Contributor

var azure = AuthHelper.CreateAzureClient();

var containerGroup = azure.ContainerGroups.Define(containerName)
    .WithRegion(location)
    .WithExistingResourceGroup(resourceGroup)
    .WithLinux()
    .WithPublicImageRegistryOnly()
    .WithoutVolume()
    .DefineContainerInstance(instanceName)
    .WithImage(containerImage)
    .WithoutPorts()
    .WithCpuCoreCount(2)
    .WithMemorySizeInGB(3.5)
    .WithEnvironmentVariables(env)
    .Attach()
    .WithRestartPolicy(ContainerGroupRestartPolicy.Never)
    .Create();

Example 2 - Purge CDN endpoint:

Required role: CDN Profile Contributor

var azure = AuthHelper.CreateAzureClient();
azure.CdnProfiles.PurgeEndpointContent(resourceGroup, profileName, endpointName, new List<string>() { "/*" });

Found something inaccurate or plain wrong? Was this content helpful to you? Let me know!

šŸ“§ codez@deedx.cz