Loupe

Architecture et déploiement d’un modèle Azure Resource Manager

Avec la release du nouveau portail et l’arrivée de Azure PowerShell 1.0, le nouveau modèle de déploiement « Azure Resource Manager » est plus que jamais au centre de l’actualité Azure.

Avec Azure Resource Manager, il est maintenant possible de provisionner des environnements cloud dans Azure en deux étapes :

  1. Définition des ressources cloud en json (modèle de déploiement)
  2. Requête POST vers les api ARM pour provisionner les ressources dans un groupe de ressource défini

L’objectif de cet article est de créer un modèle de déploiement en json, d’en étudier le contenu et de déployer ses ressources en PowerShell.

 

Architecture et création du modèle de déploiement en json

Lorsque l’on veut créer un modèle de déploiement ARM, il faut essayer d’imaginer son modèle de déploiement comme une classe que l’on rédigerait, car nous y retrouvons des éléments qui nous sont familiers :

  • Des paramètres
  • Des variables
  • Des ressources
  • Des « outputs »

 

Les paramètres sont fournis avant l’exécution du déploiement pour injecter des données dans le modèle de déploiement, ils possèdent un type (string, int, bool, object ou array), il est possible de leur spécifier une valeur par défaut ou une collection de valeur autorisées. Les valeurs des paramètres peuvent être définies dans un second fichier .json.

Les variables permettent de créer de la logique (de nommage par exemple) à l’intérieur du modèle de déploiement, elles sont optionnelles comme les paramètres. Les ressources doivent quant à elle être obligatoirement présentes dans le modèle, elles correspondent aux « ressources Azure » que nous voulons déployer (storage, machine virtuelle, website…) enfin, les « outputs » correspondent aux résultats à afficher après du déploiement.

En plus de ces éléments, il est nécessaire de spécifier deux informations :

   - La version du modèle json

   - Le schéma (url du fichier json qui décrit la version du json utilisé dans le modèle)

 

A l’intérieur du modèle, il est possible d’utiliser des « fonctions » qui permettent d’effectuer des traitements sur les chaines de caractères, sur les types numériques, ou encore créer des boucles pour créer plusieurs instances de ressources. La liste complète des fonctions utilisables est disponible ici. De plus il est possible d’utiliser des « resource expressions », ces dernières permettent de récupérer des informations sur les ressources Azure (identifiant, clef d’accès), sur la souscription Azure utilisée pour le déploiement ou encore sur le groupe de ressources dans lequel les ressources du modèle vont être déployé.

Dans le Template d’exemple ci-dessous on utilise l’expression « resourceGroup() » pour récupérer l’emplacement géographique du groupe de ressources de déploiement : resourceGroup().location, on pourrait de même récupérer l’identifiant du groupe de ressources de la manière suivante : resourceGroup().id.

Pour éviter d’avoir un modèle de déploiement trop important, l’exemple suivant permet simplement de provisionner un site web avec service plan associé. Ce site web doit se connecter à une base donnée SQL Azure :

 

{
  "$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "websiteName": { "type": "string", "minLength": 1 },
    "sqlServerName": { "type": "string" },
    "databaseName": { "type": "string" },
    "databaseLogin": { "type": "string" },
    "databasePassword": { "type": "string" }
  },
  "variables": {
    "hostingPlanName": "[concat(parameters('websiteName'), '-', 'hp')]"
  },
  "resources": [
    {
      "apiVersion": "2015-08-01",
      "name": "[variables('hostingPlanName')]",
      "type": "Microsoft.Web/serverfarms",
      "location": "[resourceGroup().location]",
      "tags": {
        "displayName": "HpIs"
      },
      "sku": {
        "name": "F1",
        "capacity": 1
      },
      "properties": {
        "name": "[variables('hostingPlanName')]"
      }
    },
    {
      "apiVersion": "2015-08-01",
      "name": "[parameters('websiteName')]",
      "type": "Microsoft.Web/sites",
      "location": "[resourceGroup().location]",
      "tags": {
        "displayName": "WebsiteIs"
      },
      "dependsOn": [
        "[concat('Microsoft.Web/serverfarms/', variables('hostingPlanName'))]"
      ],
      "properties": {
        "name": "[parameters('websiteName')]",
        "serverFarmId": "[resourceId('Microsoft.Web/serverfarms', variables('hostingPlanName'))]",
        "siteConfig": {
          "appSettings": [
            {
              "name": "MyAppSetting",
              "value": "Hello world"
            }
          ],
          "connectionStrings": [
            {
              "ConnectionString": "[concat('Data Source=tcp:', parameters('sqlServerName'), 'database.windows.net' , ',1433;Initial Catalog=', parameters('databaseName'), ';User Id=', parameters('databaseLogin'), '@', parameters('sqlServerName'), ';Password=', parameters('databasePassword'), ';')]",
              "Name": "DefaultConnection",
              "Type": 2
            }
          ]
        }
      }
    }
  ],
  "outputs": {
    "Result": {
      "type": "string",
      "value": "Deployment ok :)"
    }
  }
}

 

Détails du modèle de déploiement

Ce modèle prend en paramètre une chaine de caractère qui correspondra au « nom » du site web et quatre paramètres relatifs à la base de données à laquelle le site web doit se connecter (nom du serveur, nom de la base de données, nom d’utilisateur et password).

En s’intéressant de plus près aux nœuds « Resources ». On remarque que chaque ressource est définie par un nom, un type, un emplacement géographique et un ensemble de propriétés propre au type de ressource. Puisque le déploiement se fera au sein d’un groupe de ressource, il peut être utile de tagger les ressources directement dans la modèle de déploiement, c’est l’objectif de l’attribut « Tag ».

Deux attributs méritent une petite explication :

  • apiVersion
  • dependsOn

 

L’attribut « apiVersion » spécifie la version de l’api à utiliser pour créer la ressource. Plusieurs versions d’api peuvent être disponibles pour créer un type de ressource, chaque nouvelle version propose des nouvelles fonctionnalités qui peuvent engendrer des modifications du modèle, il faut donc faire attention à ce paramètre. La bonne pratique est de toujours utiliser la dernière api disponible, mais il est tout à fait possible d’utiliser des api plus anciennes. Pour chaque version d’api, le type de ressource possède un template de définition, que l’on retrouve via l’url définie dans l’attribut « schema » du modèle.

L’attribut « dependsOn » permet d’ordonnancer le déploiement des ressources. Dans notre cas, le service plan doit être provisionné avant le site web, puisque le site web à besoin d’un service plan pour être déployé. Le second exemple qui permet d’illustrer l’utilisation de « dependsOn » est le provisionning d’une machine virtuelle : Pour être déployée une machine virtuelle a besoin d’un compte de stockage pour stocker son disque OS sous forme de .vhd, le compte de stockage doit donc être créé avant la vm, le « dependsOn» permet donc de définir la création du compte de stockage en amont de la vm.

Au niveau du website (la ressource de type « Microsoft.Web/sites ») j’ai défini plusieurs « app settings » et une « connexion string », pour créer cette chaine de connexion on utilise la fonction « Concat » qui permet de concaténer des chaines caractères.

Ce Template pourrait par exemple être utilisé pour déployer des environnements de développement, de recette et de production, il suffit simplement de changer les « app settings » et la chaine de connexion lors du déploiement.

Au niveau du service plan (ressource de type Microsoft.Web/serverfarms), on remarque un attribut « sku », il correspond au « pricing tier » du service plan. Ici j’ai choisi un service plan de type free, avec une seule instance de web worker. De même les valeurs données aux « name » et « capicity » de l’attribut « sku » pourraient très bien être insérées en tant que paramètre et ainsi s’adapter aux différent types de déploiement possible (dev, recette, prod…).

 

Comment créer ou trouver son modèle de déploiement ARM ?

Il existe plusieurs façons de trouver des templates de déploiement ARM :

 

La solution la plus simple est de récupérer les templates proposés par Visual Studio : Pour cela, il faut créer un projet de type “Azure Resource Group” :

arm-project   select-template

 

Visual Studio propose d’ailleurs un éditeur json intégré et fournit un script de déploiement PowerShell pour déployer directement le template json. Cette solution est simple pour les utilisateurs de Visual studio ! Il existe cependant deux alternatives pour trouver des Templates ARM sans Visual Studio : La première se nomme « Azure Quickstart Template », c’est une bibliothèque de template où de nombreux templates sont disponibles. La seconde alternative se nomme « Azure Resource Explorer », cette plateforme web permet d’accéder aux ressources Azure de ses souscriptions en nous permettant d’explorer les appels au Api ARM. Il est ainsi facile de récupérer les templates json de tous les types de ressources Azure déployables avec ARM.

 

Comme tous les fournisseurs de ressources Azure ne sont pas actuellement utilisables avec Azure Resource Manager, on peut voir un état des ressources déployables via ARM ici

 

Déploiement du modèle en PowerShell

Maintenant que nous avons notre modèle de déploiement, il est temps de déployer ses ressources en PowerShell dans un groupe de ressources existant  :

#Signin in my Azure Subscription
Login-AzureRmAccount

Get-AzureRmContext

#Existing resource group to deploy template resources
$RgName = "armPlayground-rg";

$templateFile = "C:\AzureARMTemplates\DeploymentTemplate.json";

#Define parameters to inject in the template deployment
$params = @{websiteName="myAwsFromArmTemplate";sqlServerName="mySqlServer";databaseName="mySqlDb";databaseLogin="loginTest";databasePassword="PasswordTest"}

New-AzureRmResourceGroupDeployment -ResourceGroupName $RgName -TemplateFile $templateFile -TemplateParameterObject $params

A la fin du déploiement, on voit s'afficher dans la console les « outputs » définis dans le modèle de déploiement :

image

 

Happy Coding Sourire

Ces billets pourraient aussi vous intéresser

Vous nous direz ?!

Commentaires

comments powered by Disqus