Présentation de Terraform

Terraform est un outil open-source développé par HashiCorp, et utilisé pour provisionner et gérer des infrastructures IT dans le Cloud. Écrit en Go et fonctionnant en mode Infrastructure as a Code (IAC), il permet d’administrer une infrastructure grâce à du code au lieu de procéder à un ensemble d’opérations manuelles.

La force de Terraform est de reposer sur un langage de description d’infrastructure simple et lisible, on parle ici de HCL. L’approche IAC de Terraform permet de gérer le versioning d’une infrastructure en lui ajoutant ou retirant des composants.

Voici quelques articles pour débuter avec Terraform :

 

Objectif de cet article

Dans cet article, nous allons voir comment utiliser conjointement Terraform et Azure DevOps dans l’optique de déployer une infrastructure Azure, de manière automatique et continue.

Nos buts ici sont les suivants :

  1. Définir une stack Terraform simple,
  2. Intégrer Terraform dans un pipeline de Release continue de Azure DevOps.

Notre exemple portera sur les ressources suivantes :

  • 1 Web API
  • 1 SQL Database
  • 1 KeyVault

La Web API aura besoin de connaître la chaîne de connexion de la base. Afin de ne pas exposer de données sensibles, cette chaîne de connexion sera stockée dans le KeyVault lors de l’exécution de Terraform.

Les environnements que nous mettrons en place seront : DEV, REC et PRD

L’ensemble du code source est disponible sur GitHub.

 

Initialisation du projet

Pour cette première étape de ce tutoriel, connectons-nous à Azure DevOps et créons un nouveau projet que nous nommons TerraDevOps, puis clonons-le pour commencer à travailler !

Voici la structure de fichier que nous allons adopter :

|-- src\
|-- terraform\
|-- README.md
  • src\ contiendra les sources de la Web API,
  • terraform contiendra l’ensemble des fichiers de la stack applicative.

 

Côté applicatif

Commençons par créer une API ASP.NET Core dans le répertoire src\

 

Création d'une API ASP.NET Core dans le répertoire src\

 

Création d'une API ASP.NET Core dans le répertoire src\ 2

 

Afin de protéger la chaîne de connexion à la base, nous allons avoir recours au service KeyVault d’Azure. Pour pouvoir y accéder, ajoutons la dépendance : Microsoft.Extensions.Configuration.AzureKeyVault.

Microsoft.Extensions.Configuration.AzureKeyVault

Ajoutons un fichier web.config afin d’éviter l’erreur suivante lors du build dans Azure DevOps :

No web project was found in the repository. Web projects are identified by presence of either a web.config file or wwwroot folder in the directory. Project file(s) matching the specified pattern were not found.

 

Éditons maintenant le fichier Program.cs :

 

Puis, éditons le fichier Startup.cs :

 

Ensuite, modifions le fichier ValuesController.cs :

 

Et enfin, éditons le fichier appsettings.json :

 

  • KeyVaultName : Correspond au nom de la ressource KeyVault.
  • AzureADApplicationId : GUID de l’application donnant l’accès au KeyVault.
  • AzureADPassword : Est le Password de l’application donnant l’accès au KeyVault.

Voyons comment récupérer les valeurs des champs AzureADApplicationId & AzureADPassword.

Rendons-nous dans Azure Active Directory et allons dans la partie App registrations.

 

Utilisation de Terraform dans Azure DevOps

 

Ajoutons maintenant une seconde key :

 

Utilisation de Terraform dans Azure DevOps

 

Puis, mettons à jour le fichier appsettings.json avec la clé générée une fois l’action Save réalisée :

 

N’oublions pas de procéder à un push des modifications que nous venons de faire sur le repository.

À ce stade, l’API ne peut pas fonctionner car nous n’avons pas la ressource KeyVault de déployée.

 

Terraform / Infrastructure

Côté Terraform, nous allons procéder à la création des différents fichiers :

|-- src\
|-- terraform\
     |-- main.tf
     |-- outputs.tf
     |-- provider.tf
     |-- variables.tf
     |-- variables.tfvars
|-- README.md

 

Le fichier main.tf

Ce fichier définit l’ensemble des ressources que Terraform doit gérer.

 

Notons la syntaxe du nom de la ressource key_vault_secret_connectionstring : ConnectionString–Default. Lors de l’exécution de la Web Api, il sera possible d’accéder à la valeur via :

 

Comme nous l’avons vu précédemment, l’objet configuration est configuré pour récupérer des secrets dans le KeyVault.

 

outputs.tf

Ce fichier définit les outputs que retournera Terraform une fois les ressources créées.

 

provider.tf

La section backend permet de stocker le fichier tfstate sur un Storage Account (pour en savoir plus).

 

Notons les clés suivantes :

  • storage_account_name = “shared__application__tfsa”
  • key = “terraform-__environment__.tfstate”
  • access_key = “__tf_storage_account_key__”

Les différents tokens __token_name__ seront remplacés automatiquement avant le déploiement de l’infrastructure.

 

variables.tf

Ce fichier permet de définir les différentes variables utilisées.

 

variables.tfvars

Ce fichier définit les valeurs des variables. Dans notre cas, nous utilisons des tokens qui seront automatiquement remplacés lors du déploiement, en fonction de l’environnement cible.

 

Certaines variables sont indépendantes de l’environnement (location, application) et d’autres non (environement, sql_server_*).

N’oublions pas, encore une fois, de pusher les modifications.

 

Création du pipeline dans Azure DevOps

Une fois la Web Api et le Terraform en place, nous pouvons mettre en place la CI/CD.

 

Build

Créons une nouvelle Build Pipeline.

Commençons par cliquer sur le lien Use the visual designer pour passer en mode visuel.

Utilisation de Terraform dans Azure DevOps

 

Afin de nous simplifier la tâche, restons sur la branche master.

Utilisation de Terraform dans Azure DevOps

 

Dans un second temps, sélectionnons une build de type ASP.NET Core pour compiler notre Web API.

Utilisation de Terraform dans Azure DevOps

 

Modifions uniquement au niveau du step Publish la valeur du champ Arguments :

Utilisation de Terraform dans Azure DevOps

 

Ensuite, ajoutons une étape de type Copy files avant le Publish Artifact. Cette étape sert à embarquer les fichiers de Terraform dans l’artifact.

Utilisation de Terraform dans Azure DevOps

Utilisation de Terraform dans Azure DevOps

 

Enfin, procédons au lancement de notre première build. Si tout se passe bien, nous obtenons l’artifact suivant :

Utilisation de Terraform dans Azure DevOps

 

Au final, on y retrouve bien les éléments suivants :

  • drop\MyWebApi\MyWebApi.zip : zip contenant les binaires de la Web Api.
  • drop\Terraform* : les fichiers de la stack Terraform.

 

Définition de la Release

Créons à présent une nouvelle Release Pipeline, pour se faire, nous partons du template Empty job.

Utilisation de Terraform dans Azure DevOps

 

Dans un second temps, renommons le premier stage DEV.

Utilisation de Terraform dans Azure DevOps

 

Puis, nous devons ajouter un artifact.

Utilisation de Terraform dans Azure DevOps

 

Activons le Continuous deployment trigger pour lancer une release sur DEV dès qu’une build a été exécutée (il faudra également, au niveau de la build, activer l’intégration continue pour qu’une build soit exécutée dès qu’un push est effectif sur le repository).

Utilisation de Terraform dans Azure DevOps

 

Pour utiliser Terraform, nous avons besoin de :

  1. créer son backend sur Azure Storage (Blob),
  2. récupérer la Key de ce Storage et de l’injecter dans les variables pour pouvoir écrire/lire dans le Blob.

Première étape, ajoutons une étape de type Azure CLI pour la création du backend :

Utilisation de Terraform dans Azure DevOps

 

Inline script :

 

Ce script permet de créer les élèments suivants :

  1. un Resoure Group, indépendant de l’environnement déployé,
  2. un Storage Account,
  3. un Blob nommé terraform qui contiendra les tfstates de chaque environnement déployé.

Ajoutons ensuite un second step de type Azure Powershell script (en version 4.* (preview) pour le support de l’extension Az).

Utilisation de Terraform dans Azure DevOps

 

Inline script :

 

Ce script récupère la Key du Storage Account et l’injecte dans la variable tf_storage_account_key (que nous ferons un peu plus loin).

Les 2 étapes suivantes permettent de substituer les tokens présents dans les fichiers Terraform.

Utilisation de Terraform dans Azure DevOps

Utilisation de Terraform dans Azure DevOps

Utilisation de Terraform dans Azure DevOps

 

Pour chacune de ces 2 étapes, n’oublions pas de changer les Token prefix et suffix dans la section Advanced (avec double-underscores).

Utilisation de Terraform dans Azure DevOps

 

Ajoutons les steps suivantes qui concernent l’exécution de Terraform :

  • init
  • apply (en approbation automatique)

Remarque : idéalement, nous devrions ajouter le step validate juste avant le step apply afin de valider la stack avant exécution de celle-ci.

Utilisation de Terraform dans Azure DevOps

Utilisation de Terraform dans Azure DevOps

Utilisation de Terraform dans Azure DevOps

 

Ajoutons finalement la step pour déployer la Web Api sans oublier la transformation du fichier appsettings.json.

Utilisation de Terraform dans Azure DevOps

 

Une fois le stage DEV finalisé, faisons-en un clone que l’on nomme REC. Réitérons l’opération RECPRD.

Utilisation de Terraform dans Azure DevOps

 

Activons aux stages REC et PRD l’option Pre-deployment approvals :

Utilisation de Terraform dans Azure DevOps

 

Notre pipeline étant défini, il nous reste maintenant à définir les variables.

Utilisation de Terraform dans Azure DevOps

 

Les valeurs des clés KeyVaultName, AzureADApplicationId et AzureADPassword seront injectées dans la configuration de la Web Api lors du dernier step du pipeline.

 

Exécution du pipeline

Lançons finalement notre première Release !

Une fois déployée, nous nous retrouvons avec 2 nouveaux Resource Groups :

  • dev-mywebapi
  • shared-mywebapi

Dans shared-mywebapi, nous retrouvons le Storage Account et son Blob qui contient le tfstate du déploiement de l’environnement DEV.

 

Utilisation de Terraform dans Azure DevOps

Utilisation de Terraform dans Azure DevOps

 

dev-mywebapi contient quant à lui les ressources applicatives.

Utilisation de Terraform dans Azure DevOps

 

Reste à tester que notre Web Api fonctionne bien :

 

… et à déployer les environnempents de REC et PRD 😃

Conclusion

Dans cet article, nous avons vu comment provisionner une infrastructure Azure avec Terraform, le tout, déployé de manière continue au travers d’Azure DevOps. Il est évident que tous les aspects n’ont pas été couverts, mais cela reste un point d’entrée pour notre démarche DevOps.

 

livre blanc From Zero to Hero 1 Infra as code