Automatiser le déploiement d’Azure App Configuration

Florian CAILLAUD
Publié par Florian CAILLAUD
Catégorie : App Configuration / Azure / DevOps Template ARM
02/04/2021

Introduction

 

Azure App Configuration est un service Azure permettant de centraliser la configuration pour un ensemble d’applications dans le Cloud.

L’avantage d’une telle ressource est d’externaliser la configuration. Ainsi, elle n’est pas présente directement dans le code ni même éparpillée dans une multitude de services Azure. Il sera alors possible de gérer dynamiquement, et de manière centralisé la configuration des applications. Cela permet par exemple d’éviter de redéployer ou redémarrer les applications pour mettre à jour la configuration.

Dans ce cadre, Azure App Configuration peut servir à mettre en œuvre des stratégies de déploiement « feature flag ». On peut aussi simplement construire des configurations plates ou hiérarchiques avec potentiellement des valeurs secrètes (lien avec Azure Keyvault).

De plus Azure App Configuration est scalable et donc gère nativement la montée en charge. Ce service offre également une gestion de version.

En général, Les applications utilisent cette ressource durant leur exécution. Cependant, il est possible de s’en servir à des fins de déploiement. Il faut néanmoins faire la distinction entre Azure App Configuration, Azure Keyvault et les variable groups (ou autres variables de pipeline) dans Azure DevOps.

Dans Azure DevOps, on ne stockera que les valeurs de configuration propres au déploiement. Il est également possible d’inclure des valeurs secrètes ou de faire un lien avec Azure KeyVault. De son côté, Azure Keyvault sera utilisé pour le stockage de valeurs secrètes ou de certificats.

Si l’utilisation d’Azure App Configuration est justifiée, alors voici quelques indications sur la manière de déployer cette ressource.

 

Azure App Configuration ARM template

 

Il est possible de créer ce type de ressource directement depuis le portail Azure. Néanmoins, une bonne pratique serait de mettre en place un déploiement automatisé de la ressource. Pour ce faire, nous utiliserons un template ARM décrivant notre App Configuration.

Voici un template minimal d’App Configuration :

 

{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "configStoreName": {
      "type": "string"
    },
    "keyValueNames": {
      "type": "array",
      "defaultValue": [ "myKey", "myKey$myLabel" ]
    },
    "keyValueValues": {
      "type": "array",
      "defaultValue": [ "Key-value without label", "Key-value with label" ]
    },
    "contentType": {
      "type": "string",
      "defaultValue": "the-content-type",
      "metadata": {
        "description": "Specifies the content type of the key-value resources. For feature flag, the value should be application/vnd.microsoft.appconfig.ff+json;charset=utf-8. For Key Value reference, the value should be application/vnd.microsoft.appconfig.keyvaultref+json;charset=utf-8. Otherwise, it's optional."
      }
    },
    "tags": {
      "type": "object",
      "defaultValue": {
        "tag1": "tag-value-1",
        "tag2": "tag-value-2"
      }
    }
  },
  "resources": [
    {
      "type": "Microsoft.AppConfiguration/configurationStores",
      "apiVersion": "2020-07-01-preview",
      "name": "[parameters('configStoreName')]",
      "location": "[resourceGroup().location]",
      "sku": {
        "name": "standard"
      }
    },
    {
      "type": "Microsoft.AppConfiguration/configurationStores/keyValues",
      "apiVersion": "2020-07-01-preview",
      "name": "[concat(parameters('configStoreName'), '/', parameters('keyValueNames')[copyIndex()])]",
      "copy": {
        "name": "keyValueCopy",
        "count": "[length(parameters('keyValueNames'))]"
      },
      "dependsOn": [
        "[parameters('configStoreName')]"
      ],
      "properties": {
        "value": "[parameters('keyValueValues')[copyIndex()]]",
        "contentType": "[parameters('contentType')]",
        "tags": "[parameters('tags')]"
      }
    }
  ]
}

 

Ici, il faut noter plusieurs choses.

Premièrement, il est possible d’avoir un template par environnement avec des valeurs initiales statiques. Mais ces valeurs peuvent également être paramétrables (voir keyValueNames et keyValueValues du template). Elles seront définies à la volée, lors du déploiement. Le déploiement pourra se faire avec Powershell, Azure DevOps ou GitHub. Chacun aura son mécanisme de variable.
Il est également possible de ne déployer qu’un ou plusieurs couples de clé-valeur, en utilisant uniquement la ressource de type Microsoft.AppConfiguration/configurationStores/keyValues dans notre template.

Ensuite, chaque clé peut être liée à un label pour une meilleure organisation. Cela peut renseigner une version ou un environnement, par exemple. Pour ajouter ce label, il faut le placer après le nom de la valeur et un ‘$’ (myKey$myLabel dans le template ci-dessus).

Enfin, certains caractères ne sont pas admis dans un template ARM. Pour la définition des clés, des labels mais surtout des valeurs, il est régulièrement nécessaire d’utiliser des caractères spéciaux. Dans ce cas, dans un premier temps, la valeur doit être URL encoded (remplacement des caractères spéciaux par %…). Puis il faut remplacer les % par des ~ et les ~ par des ~7E. Par exemple, pour une clé « AppName:DbEndPoint » et un label « Test », on utilisera la valeur « AppName~3ADbEndPoint$Test ».

 

Déploiement de l’ARM

 

Comme mentionné plus haut, il y a plusieurs façons de déployer ce template ARM.

Avec Powershell, il faudra s’authentifier sur la souscription Azure voulue. Puis, nous utiliserons la commande New-AzResourceGroupDeployment en spécifiant le resource group cible, le template et éventuellement le fichier de paramètres (doc).

Sur Azure DevOps, on utilisera la tâche ARM template deployment au sein d’un pipeline (avec le designer ou un script YAML). Les informations nécessaires seront :

  • la Service Connection (définie dans le projet pour permettre l’accès au resource group cible)
  • la souscription,
  • le resource group puis le template et le fichier de paramètres associés (doc designer doc YAML).

Ici, il sera possible de redéfinir la valeur des paramètres à la volée en utilisant des variables de pipelines ou des variables groups.

Et enfin, avec GitHub, la mise en place d’une GitHub Action sera nécessaire (doc). Le mécanisme est très similaire à celui d’Azure DevOps.