Blogue

Technologie
L’Infrastructure en tant que code dans un monde DevOps et Azure
23 octobre 2017
par Maxime Plante

Vous avez sûrement déjà entendu parler du DevOps… tout le monde en a entendu parler! Et puis, c’est bien la raison pour laquelle vous êtes là, non? Mais connaissez-vous l’infrastructure en tant que code (IaC)? Ces jours-ci, elle est sur toutes les lèvres.

Selon Wikipedia, l’infrastructure en tant que code est le processus permettant de gérer et d’approvisionner les centres de données informatiques (data centers) à partir de fichiers de définition lisibles par les machines, plutôt que par des outils physiques de configurations matérielles ou de configurations virtuelles [1]. Autant les équipements physiques, comme les serveurs directement opérationnels (bare-metal servers), que les machines virtuelles (virtual machines) et leurs ressources de configuration associées sont appelés « infrastructure », même s’ils n’ont rien à voir avec l’infrastructure en tant que telle. Les définitions peuvent se trouver dans un système de gestion de versions (version control system). L’infrastructure peut utiliser des scripts ou une programmation déclarative, plutôt que des processus manuels, mais le terme s’utilise le plus souvent lorsqu’on favorise les approches déclaratives.       

Mais qu’est-ce que cela signifie lorsque l’objectif de votre entreprise est d’établir des pratiques d’utilisation DevOps des outils Microsoft et Azure dans le « monde réel »?

Établie depuis 2006 en tant que compagnie DevOps, Emyode a récemment eu la possibilité d’automatiser l’IaC à partir des meilleures connaissances de ses techniciens.

Laissons donc les experts décider de ce qu’il y a de bon et de mieux pour les applications.

 

Hypothèses

 

Comment concevoir votre modèle

  1. Modèles Visual Studio (WebApp) : ce modèle vous donne un léger avantage grâce à quelques paramètres prédéfinis de même qu’une structure de base pour application Web. Ce modèle comprend également des composants AppInsight. N’oubliez pas de les retirer si vous prévoyez ne pas les utiliser.
  2. Avant d’ajouter toute autre ressource, assurez-vous de nommer les paramètres existants selon vos besoins. Cela vous évitera des problèmes si vous devez utiliser ces paramètres dans de nouvelles ressources.
    • Chaque paramètre utilisé en tant que mot de passe ou jeton doit être défini comme « chaîne sécurisée » (securestring).
    • En supposant que vous avez déjà une application Web, vous devez lui ajouter chaque paramètre configurable (c.-à-d. web.config) en tant que paramètre modifiable (ou comme j’aime les appeler « devops-able ») dans tout déploiement.
      « parameters »: {
      « Environment »: {“type”: “string”,“defaultValue”: “qa”,“allowedValues”: [ “dev”, “qa”, “uat”, “staging”, “prod” ],“minLength”: 1 }
    • Chez Emyode, nous avons mis en place une convention d’appellation simple, mais directe, pour mieux définir et maintenir les services Azure que nous créons. Pour cette raison, nous mettons en place dans le modèle différentes variables qui concaténeront les noms des différents services selon l’environnement qui lui est consacré. Le déploiement d’un environnement QA par exemple peut se concaténer ainsi :
      fooqawebapp”.
      « variables »: {
      « FooWebAppName »: « [concat(‘Foo’, parameters(‘Environment’), ‘webapp’)] »} […]
    • Puisque nous allons, entre autres, déployer une application Web, vous devrez ajouter une ressource de déploiement Web. Vous pouvez faire un clic droit sur le nœud/ressource et l’ajouter en utilisant l’assistant. Le résultat devrait ressembler à ceci dans votre nœud d’application Web.
      {
      « name »: « MSDeploy »,
      « type »: « extensions »,
      « location »: « [resourceGroup().location] »,
      « apiVersion »: « 2015-08-01 »,
      « dependsOn »: [
      « [resourceId(‘Microsoft.Web/sites’, variables(‘webSiteName’))] »
      ],
      « tags »: {
      « displayName »: « SGMSWebDeployWebsite »
      },
      « properties »: {
      « packageUri »: « [concat(parameters(‘_artifactsLocation’), ‘/’, parameters(‘WebDeployWebsitePackageFolder’), ‘/’, parameters(‘WebDeployWebsitePackageFileName’), parameters(‘_artifactsLocationSasToken’))] »,
      « dbType »: « None »,
      « connectionStrings »: [
      {
      « name »: « ConnectionString »,
      « ConnectionString »: « [concat(‘Server=tcp:’, variables(‘sqlserverName’), ‘.database.windows.net,1433;Initial Catalog=’, variables(‘databaseName’), ‘;Persist Security Info=False;User ID=’, parameters(‘administratorLogin’), ‘;Password=’, parameters(‘administratorLoginPassword’), ‘;MultipleActiveResultSets=False;Encrypt=True;
      TrustServerCertificate=False;Connection Timeout=30;’)] »,
      « Type »: 2
      }
      ],
      « setParameters »: {
      « IIS Web Application Name »: « [variables(‘webSiteName’)] »
      }
      }
      }

      {
      "name": "MSDeploy",
      "type": "extensions",
      "location": "[resourceGroup().location]",
      "apiVersion": "2015-08-01",
      "dependsOn": [
      "[resourceId('Microsoft.Web/sites', variables('webSiteName'))]"
      ],
      "tags": {
      "displayName": "SGMSWebDeployWebsite"
      },
      "properties": {
      "packageUri": "[concat(parameters('_artifactsLocation'), '/', parameters('WebDeployWebsitePackageFolder'), '/', parameters('WebDeployWebsitePackageFileName'), parameters('_artifactsLocationSasToken'))]",
      "dbType": "None",
      "connectionStrings": [
      {
      "name": "ConnectionString",
      "ConnectionString": "[concat('Server=tcp:', variables('sqlserverName'), '.database.windows.net,1433;Initial Catalog=', variables('databaseName'), ';Persist Security Info=False;User ID=', parameters('administratorLogin'), ';Password=', parameters('administratorLoginPassword'), ';MultipleActiveResultSets=False;Encrypt=True;
      TrustServerCertificate=False;Connection Timeout=30;')]",
      "Type": 2
      }
      ],
      "setParameters": {
      "IIS Web Application Name": "[variables('webSiteName')]"
      }
      }
      }
      {
      "name": "MSDeploy",
      "type": "extensions",
      "location": "[resourceGroup().location]",
      "apiVersion": "2015-08-01",
      "dependsOn": [
      "[resourceId('Microsoft.Web/sites', variables('webSiteName'))]"
      ],
      "tags": {
      "displayName": "SGMSWebDeployWebsite"
      },
      "properties": {
      "packageUri": "[concat(parameters('_artifactsLocation'), '/', parameters('WebDeployWebsitePackageFolder'), '/', parameters('WebDeployWebsitePackageFileName'), parameters('_artifactsLocationSasToken'))]",
      "dbType": "None",
      "connectionStrings": [
      {
      "name": "ConnectionString",
      "ConnectionString": "[concat('Server=tcp:', variables('sqlserverName'), '.database.windows.net,1433;Initial Catalog=', variables('databaseName'), ';Persist Security Info=False;User ID=', parameters('administratorLogin'), ';Password=', parameters('administratorLoginPassword'), ';MultipleActiveResultSets=False;Encrypt=True;
      TrustServerCertificate=False;Connection Timeout=30;')]",
      "Type": 2
      }
      ],
      "setParameters": {
      "IIS Web Application Name": "[variables('webSiteName')]"
      }
      }
      }
  3. Configuration d’artefacts (créés lorsque vous ajoutez la ressource de déploiement Web) : avant de pouvoir publier votre application sur Azure et d’y « pousser » votre contenu IaC, vous devrez créer un nouvel espace de stockage dans son propre groupe de ressources. En général, cela fait référence à un stockage Azure. De préférence, il vaut mieux le faire avant de commencer à publier toute version.
    « _artifactsLocation »: {
    « type »: « string »
    },
    « _artifactsLocationSasToken »: {
    « type »: « securestring »
    }
  4. AppSettings (paramètres d’application) : dans le monde réel, nous définissons tous des paramètres précis pour chaque application. La plupart du temps, ils sont différents selon chaque environnement. À ce stade, vous devez donc créer ceux que contiendra la définition de votre application Web.
  5. Fichier de paramètres de modèle ARM : maintenant, il vous faut décider de la stratégie à adopter : utiliser un fichier de paramètres de modèle et/ou outrepasser les paramètres de modèle plus tard lorsque vous procéderez à la gestion des mises en production. Avoir plusieurs paramètres JSON pour chaque environnement rendra probablement le modèle plus « devops-able », mais parfois, pour certaines raisons, avoir la capacité d’outrepasser ces paramètres dans l’interface UI peut être très utile.
  6. Situation de compétition : il est très important de déclarer toutes les propriétés reliées dans la définition de votre composant. Lorsque vous rencontrez une situation de compétition – consultez cet article.  C’est une situation très difficile à déboguer, car parfois votre déploiement réussira, parfois non, et la plupart du temps, en raison d’une erreur bizarre, sans aucun lien apparent.

 

Déploiement

Configurer les builds

Pourvu que le build fonctionne, peu importe que vous utilisiez TFS ou GIT comme contrôle de code source, tout va pour le mieux. Ce dont il faut vous assurer est de pouvoir saisir le bon modèle ARM selon votre stratégie de gestion des branches. Aux fins de cet article, nous allons lire le modèle ARM à partir des artefacts générés. Mais vous pourriez décider de joindre une étape pour les copier dans une structure de votre choix en ajoutant une tâche pour la copie des fichiers.

 

Configurer le gestionnaire de mises en production

Configuration des artefacts

Puisque nous avons utilisé un build TFS pour notre exemple, Build devrait être paramétré comme source type. Les 2 autres paramètres sont réellement fonction de votre nom de projet et du nom de définition du build. Aux fins de cet exemple, nous avons activé un déclencheur de déploiement continu pour tirer profit, lors du déploiement continu, de toute modification apportée.

À ce point, il y a vraiment matière à discussion!

Certaines entreprises choisiront d’avoir des versions se déployant selon un calendrier fixe, d’autres choisiront le déploiement continu avec approbations et/ou d’autres combinaisons possibles. Il s’agit d’une décision très importante qui aura un effet sur l’ensemble du processus d’assurance qualité du développement du logiciel. Elle doit être prise très au sérieux et mérite une réflexion approfondie, parce que, bien sûr, nous aimons tous avoir des logiciels de qualité.

Configuration des environnements

Selon la stratégie de l’entreprise, il est très courant de disposer d’au moins un environnement pour le développement, un pour la production, un environnement QA et un UAT.

Peu importe combien vous en avez, la recette ne change pas. Ce qui signifie que nous allons examiner un seul scénario que vous pourrez au besoin adapter facilement selon les différentes situations et variables.

Dans l’environnement Dev, puisqu’il s’agit de la première « barrière » de surveillance de la qualité, tout y est la plupart du temps « poussé » tel quel (bien sûr, des tests unitaires automatisés et ce genre de vérifications automatiques peuvent être utilisés pendant le processus build). Les déclencheurs sont programmés pour être activés après la mise en production, il n’y a aucun approbateur lors du prédéploiement.

Lors du post-déploiement, une équipe principale ou un développeur principal peut vérifier si tout fonctionne correctement dans l’environnement et approuver la version, qui devra être configurée. Pour les besoins de cet article, nous l’avons laissée à configuration automatique.

C’est ici que la partie environnement devient réellement intéressante. Pour les autres environnements (ou programmations parallèles), vous pouvez configurer différents paramètres, différentes approbations et ainsi de suite pour le prédéploiement et le post-déploiement. Cela dépend de la stratégie de votre entreprise.

Configuration des tâches pour l’environnement

Pour cette procédure pas-à-pas, nous ajouterons 2 étapes :

VIDÉO:

Cette vidéo vous montre comment outrepasser les paramètres de modèle de façon à contourner le bogue de la GUI qui crée une erreur et fait échouer votre build.

 

TL;DR: Allez à la boîte de dialogue de recherche du modèle ARM, sélectionnez un nœud, cliquez sur annuler, revenez au dialogue permettant d’outrepasser les paramètres et l’erreur aura disparu.

 

Ouf! Ça y est, c’est terminé!

 

Conclusion

Comme vous pouvez le constater, les outils sont plutôt faciles à utiliser, mais ils sont si flexibles qu’il est aisé de se perdre dans l’univers du Devops. La clé, afin de livrer des logiciels de qualité et d’avoir une chaîne de production homogène, est de prendre son temps et de bien réfléchir. N’hésitez pas à sortir un peu des sentiers battus, à créer des environnements tests en utilisant un compte VSTS pour faire l’essai de votre processus de mise en production.

Faites de petits pas. Après tout, être agile peut s’appliquer au processus de livraison de votre logiciel afin d’offrir un produit de qualité à vos clients.

Rome ne s’est pas bâtie en un jour, n’est-ce pas?