Cloud AWS : Automatisation d’un déploiement SQL Always On

Les applications web d’entreprises sont très souvent construites sur un modèle classique qui a fait ses preuves : des serveurs web front-end se chargent de prendre en compte les requêtes des clients et renvoient les résultats en s’appuyant sur des serveurs de base de données SQL en back-end. Sur AWS, le service managé RDS (Relational Database Service) peut fournir cette couche SQL et il est définitivement conseillé de l’utiliser si c’est possible. Pour les cas où il n’est pas possible d’utiliser RDS, nous avons réalisé l’automatisation d’une stack Microsoft SQL Always On dont nous allons détailler ici le fonctionnement.

L’automatisation d’une stack Microsoft SQL en « Always On » est composée de deux nœuds SQL et d’une instance « witness ». Chacune des instances est dans une zone de disponibilité AWS différente ce qui permet d’assurer la haute disponibilité de l’ensemble. Ce processus d’installation part d’une AMI générique et se termine avec un cluster SQL « Always On » pleinement fonctionnel et prêt à être utilisé.

Pour cela, nous nous appuyons sur les outils suivants:

  • Chocolatey : un gestionnaire de packets pour Windows ; il nous permet d’utiliser Powershell pour créer des scripts d’installation complexes
  • Une AMI préparée à l’avance : elle contient notamment l’outil Chocolatey et est configurée pour s’insérer dans le domaine dès son lancement
  • Terraform : un outil permettant d’écrire l’Infrastructure As Code, il est le maître d’orchestre du déploiement.

On notera également l’aspect fondamental des « User Datas » AWS, qui sont le moyen d’initier les installations et de différentier des instances pourtant toutes issues de la même AMI. Les User Datas sont en fait le script d’initialisation à l’instance, qui sera joué uniquement au premier démarrage et qui nous permet de lancer l’installation d’un premier package Chocolatey. Ce package pourra lui-même appeler d’autres installations, initiant ainsi notre chaîne d’installation automatique de l’instance.

Notre stack SQL « Always ON » Terraform commence par le lancement de deux instances EC2. Ces instances seront les deux nœuds du cluster SQL. A ce stade, on ne fait qu’installer Microsoft SQL Server sur chacune d’elles grâce à un package Chocolatey. C’est l’occasion de faire une parenthèse pour décrire un peu plus en détails la construction de nos packages.

Le package lui-même est au format NuGet et ne contient en fait que les scripts d’installation et de désinstallation, il est donc d’une taille négligeable et peut être hébergé sur n’importe quelle plateforme : une instance AWS EC2, un serveur On-Premises ou un fournisseur de service en ligne.

Les binaires nécessaires aux installations sont quant à eux stockés dans un bucket S3. Nous avons fait ce choix pour une raison simple : le coût de stockage sur S3 est dérisoire et la disponibilité du service est excellente. Le transfert de données vers l’instance est également moins coûteux, plus fiable et plus rapide depuis S3 que depuis internet ou on-premise.

Finalement, S3 héberge également des fichiers de configuration qui nous permettent de personnaliser l’installation d’un package indépendamment du code du package lui-même : par exemple pour définir les comptes de service à utiliser. Tout ce qui relève de l’environnement spécifique d’un client est paramétrable dans ces fichiers, ce qui permet de facilement adapter nos packages en minimisant le risque de « casser » quelque chose.

Fin de parenthèse, revenons à notre installation. Avant de passer à l’installation de l’instance « witness » et de monter effectivement le cluster, Terraform doit être assuré que l’installation de SQL est terminée. C’est le même type de problème de dépendance déjà évoqué lors de l’installation de la stack Active Directory.

Cette problématique est ici résolue d’une manière similaire. Après avoir lancé l’installation des serveurs SQL, Terraform rentre dans une sorte de boucle permettant d’attendre la fin d’installation de SQL. Il lance en fait deux scripts Powershell, chacun paramétré avec le nom d’une instance, qui cherchent la présence d’un fichier spécifique. Du côté des instances SQL, la chaîne d’installation de packages Chocolatey se termine par un package spécial dont la seule fonction est de créer un fichier dans S3, avec un nom calculé par rapport au nom de l’instance. Ce package est bien sûr écrit de sorte à être compatible avec le script de recherche utilisé par Terraform. Ainsi, les instances en cours d’installation peuvent signaler leur fin d’installation à Terraform, ce qui nous permet de gérer des dépendances évoluées.

Une fois le signal reçu pour les deux instances SQL, Terraform lance l’installation du serveur witness. Bien que le rôle du witness au sein du cluster soit plutôt réduit (mais indispensable), il est capital pour l’installation. Tout d’abord, un mot sur la nécessité d’un serveur witness au sein d’un cluster (pas forcément SQL Always On, c’est un besoin générique). Cette nécessité tient en un seul terme barbare : split-brain. Imaginez que pour une raison ou une autre, les deux serveurs ne puissent plus se parler mais restent accessibles du monde extérieur : chacun « penserait » que son partenaire est tombé et deviendrait primaire, entraînant alors une divergence (des bases de données, dans le cas d’un cluster SQL).

Le rôle du witness est de maintenir un token, grossièrement c’est un fichier dans un partage CIFS, qui permet à un seul des nœuds de poser un verrou. Ainsi, dans le cas décrit précédemment, seul le serveur réussissant à obtenir ce token pourra être primaire et on évite la divergence. La réalité est un peu plus complexe, mais l’idée générale est là. Venons-en donc à l’installation du witness.

L’installation du witness ne va pas se contenter de créer le partage CIFS nécessaire au futur cluster. Elle va surtout se connecter via WinRM aux deux serveurs SQL fraîchement construits pour tout configurer :

  • l’activation de la couche cluster de Windows, l’ajout des deux nœuds et du witness
  • la définition du nom du cluster qui va permettre de créer l’enregistrement DNS qui pointera toujours sur le serveur primaire
  • la création d’une première base de donnée SQL
  • l’activation de la fonctionnalité « Always ON »

L’installation du serveur witness va dérouler tous les scripts nécessaires sur chacune des instances et, finalement, on obtient le résultat escompté: un cluster SQL « Always On » fonctionnel, adressable par un nom générique et hébergeant une première base de données.

Dès cet instant, la perte du serveur SQL primaire entraine la bascule automatique vers le secondaire (qui devient de fait primaire) en quelques secondes (la limite étant le TTL de l’enregistrement DNS du nom du cluster, qui va déterminer le temps maximum qu’il faudra pour que tous les serveurs front-end pointent effectivement sur le nouveau primaire).

 

Commentaires :

A lire également sur le sujet :