Loupe

Créer ses propres outils Azure en C# avec .net core, Azure Resource Manager et WAML (Part 1)

Avec l’arrivée progressive de .net core dans l’écosystème Microsoft et l’évolution d’Azure avec ARM (« Azure Resource Manager »), les librairies permettant de manager les ressources Azure (« Windows Azure Management Librairies) ont également évolués :

  • Compatibilité avec .net Core
  • Utilisation native des API ARM

Les SDK / librairies de management Azure sont des wrappers sur les API Azure. Pour plus d’information je vous redirige vers un ancien post.

L’objectif de cet article (et du prochain) est de mettre en place une librairie .net Core qui utilise le SDK de management Azure ARM. Notre librairie va implémenter plusieurs services :

  • Un service d’authentification
  • Un service permettant de manager des groupes de ressources

Cette librairie pourra ensuite être utilisée par un projet .net Core (console et/ou web).

 

WAML, 2 API(s) Azure donc 2 SDK :

Avec une application .net classique, on utilise WAML avec les packages Nuget exposant les namespaces suivant :

  • Microsoft.WindowsAzure.Management.Website
  • Microsoft.WindowsAzure.Management.Storage
  • Microsoft.WindowsAzure.Management.*

Ces packages utilisent les api(s) ASM (Azure Service Management) pour manager les ressources Azure. Les méthodes de ces namespaces « wrappent » des appels vers cette api :

https://management.core.windows.net/<subscription-id>/services/{serviceName}/{options}?..

 

Avec une application .net Core, on utilise WAML avec les packages Nuget exposant des nouveaux namespaces :

  • Microsoft.Azure.Management.*

Ces packages utilisent quant à eux les api(s) ARM (Azure Resource Manager) pour manager les ressources Azure. L’api utilisée par les méthodes présentes dans ces namespaces est donc différente :

https://management.azure.com/subscriptions/{subscription-id}/resourcegroups/{resource-group-name}/{providers}?...

On remarque dans l’api le paramètre {resource-group-name} : toutes les opérations sur les ressources Azure s’effectueront donc toujours au sein d’un groupe de ressources.

 

Des “breakings changes” lors de l’utilisation des nouveaux namespaces ?

La première des choses à prendre en compte lorsque l’on veut utiliser WAML c’est l’authentification nécessaire pour effectuer des appels vers les API. Que l’on utilise .net classique ou .net Core, l’authentification est obligatoire et tout à fait justifiée d’ailleurs.

Que l’on utilise WAML ASM ou WAML ARM, l’authentification s’effectue via ADAL (« Active directory Authentication Librairie »).

Depuis sa version 3 cette dernière est compatible .net Core et son implémentation diffère donc légèrement par rapport à ses versions précédentes, nous verrons le code en détails un peu plus tard.

 

La librairie .net Core :

Pour débuter il est nécessaire de créer un projet de type « Class library (Package) » dans Visual Studio, l’architecture de la librairie se veut très simple : Un dossier « service » et un fichier “project.json”.

Pour respecter les paradigmes .net Core, nous allons utiliser le strict minimum dans notre librairie, soit :

  • Le package ADAL (pour l’authentification)
  • Le package “Microsoft.Azure.Management.Resources” permettant de manager les groupes de ressources

 

Voici le project.json de la librairie :

{
  "version": "1.0.0-*",
  "description": "AzureManager.Domain Class Library",
  "authors": [ "ThibautRANISE" ],
  "tags": [ "" ],
  "projectUrl": "",
  "licenseUrl": "",
  "dependencies": {
    "Microsoft.Azure.Management.Resources": "3.4.0-preview",
    "Microsoft.IdentityModel.Clients.ActiveDirectory": "3.9.302111717-alpha"
  },
  "frameworks": {
    "dnxcore50": { }
  }
}

On remarque grâce à la propriété « Framework » que notre librairie sera compilable avec .net Core Sourire 

 

Le service d’authentification :

La première étape avant d’utiliser WAML et de créer une application Azure Active Directory et lui attribuer les autorisations pour les librairies de management Azure.

Une fois l’application créée et les trois informations nécessaires récupérées : (« ClientId », « TenantId » et « RedirectUri »), nous pouvons implémenter notre service.

Ce service doit être « injectable » par IOC (« Inversion of Control »), car nous pourrions l’utiliser dans une application Web Asp net core.

Son constructeur prendra donc en entrée les trois paramètres cités précédemment ainsi qu’un email et un mot de passe qui permettront d’authentifier un utilisateur de la souscription Azure sur laquelle l’application Active directory est hébergée. Une méthode « Auth » permet quant à elle de générer un token qui sera utilisé par la suite dans toutes nos requêtes vers les api(s) de management Azure :

 

public class AuthenticationService : IAuthenticationService
{
    private string clientId;
    private string tenantId;
    private Uri redirectUri;
    private string email;
    private string password;
    private string subscriptionId;

    public AuthenticationService(string clientId, string tenantId, string redirectUri, string email, string password, string subscriptionId)
    {
        this.clientId = clientId;
        this.tenantId = tenantId;
        this.redirectUri = new Uri(redirectUri);
        this.email = email;
        this.password = password;
        this.subscriptionId = subscriptionId;
     }

     /// <summary>
     /// Authenticate a user with an Azure Active Directory App
     /// </summary>
     public async Task<ServiceClientCredentials> Auth()
     {
        var context = new AuthenticationContext(string.Format("https://login.microsoftonline.com/{0}", tenantId));

         var authenticationResult = await context.AcquireTokenAsync(
         resource: "https://management.core.windows.net/",
         clientId: clientId,
         userCredential: new UserCredential(this.email, this.password));

         string token = authenticationResult.CreateAuthorizationHeader().Substring("Bearer ".Length);

         return new TokenCredentials(token);
       }

     /// <summary>
     /// Return the subscriptionId
     /// </summary>
     public string GetSubscriptionId()
     {
        return this.subscriptionId;
     }
}

 

Utilisation du service d’authentification dans un projet console .net Core :

Maintenant que nous possédons une librairie capable de nous authentifier sur notre application Azure, nous pouvons créer une application console pour vérifier que nous récupérons avec succès le token d’authentification dont nous avons besoin pour utiliser les librairies de management Azure :

Après avoir créé le projet de type console (Package) depuis Visual studio, il faut y ajouter un fichier de configuration que nous nommons « appSettings.js » donc voici le contenu :

{
  "AzureADApp": {
    "ClientId": "XXXXXXXXXXXXXXXXXXXXXXXXXXX",
    "TenantId": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
    "RedirectUri": "http://myADALapplication"
  },
  "AzureAccount": {
    "Email": "tranise@infinitesquare.com",
    "Password": "XXXXXXXXX",
    "SubscriptionId": "XXXXXX-XXX-XXXXX-XXXXX-XXXXX"
  }
}

Ce fichier de configuration contiendra toutes les informations nécessaires à l’initialisation du service d’authentification :

public class Program
{
    public static IConfiguration configuration;

    public static void Main(string[] args)
    {
        IApplicationEnvironment app = PlatformServices.Default.Application;

        // Load configurations stored in appSettings.json
        configuration = new ConfigurationBuilder()
            .AddJsonFile(Path.Combine(app.ApplicationBasePath, "appsettings.json"))
            .AddEnvironmentVariables()
            .Build();

        Task.Run(async () =>
        {
            // Create the authentication service
            IAuthenticationService authenticationService = new AuthenticationService
                (
                    clientId: configuration["AzureADApp:ClientId"],
                    tenantId: configuration["AzureADApp:TenantId"],
                    redirectUri: configuration["AzureADApp:RedirectUri"],
                    email: configuration["AzureAccount:Email"],
                    password: configuration["AzureAccount:Password"],
                    subscriptionId: configuration["AzureAccount:SubscriptionId"]
                );

            ServiceClientCredentials credentials = await authenticationService.Auth();

        });
    }
}

L’objet de type « ServiceClientCredentials » va nous permettre d’utiliser WAML comme bon nous semble.

Dans le prochain article, nous implémenterons un nouveau service qui nous permettra de manager des groupes de ressources et nous utiliserons les credentials récupérés via le service d’authentification pour utiliser ce nouveau service.

 

Happy Coding Sourire

Ces billets pourraient aussi vous intéresser

Vous nous direz ?!

Commentaires

comments powered by Disqus