By Walid ETTAYEB

Introduction

Vous avez déjà entendu parler de Terraform, mais vous ne savez pas vraiment ce que c'est ni comment ça marche ?
Dans cet article, je vous expliquerai les concepts de base de Terraform, comment l'utiliser, comment il fonctionne et je vous expliquerai pourquoi il a gagné un tel succès au cours des dernières années. Je prévois aussi d'aborder légèrement la syntaxe de base de Terraform et le langage de configuration qu'il utilise, sans aller trop en profondeur dans les sujets plus avancés. Je poursuivrai sur ce blog avec un examen plus approfondi de la technologie à l'avenir.
Lorsque j'ai commencé à écrire cet article, j'imaginais qu'il s'agirait d'un article simple, mais au fur et à mesure, j'ai réalisé que Terraform est en fait très complexe, et l'article s'est étoffé en conséquence.

Qu'est-ce que Terraform et pourquoi toute cette agitation ?

Il y a de fortes chances que vous ayez trouvé cet article parce que quelqu'un dans votre entreprise vous a dit "Nous devrions utiliser Terraform pour cela" ou parce que vous êtes tombé sur un dépôt git qui disait "Vous pouvez utiliser ces scripts Terraform pour déployer cette solution". N'ayez crainte, cher lecteur, je me suis déjà trouvé à votre place il y a plus de 12 mois et j'ai eu du mal à sortir de la confusion.

Terraform en bref

Dans sa forme la plus basique, Terraform est une application qui convertit des fichiers de configuration connus sous le nom de HCL (Hashicorp Configuration Language) en infrastructure du monde réel, grâce à des fournisseurs de cloud computing tels que AWS, Azure ou GCP.
Ce concept de conversion de fichiers de configuration en ressources réelles est connu sous le nom d'IaC (Infrastructure as Code) et constitue la nouvelle mode dans le monde du génie logiciel. Et la raison pour laquelle il devient si populaire actuellement est que ce code peut vivre aux côtés du code de votre application dans des dépôts, pour être contrôlé par version et facilement intégré dans vos pipelines CI/CD.

Comme beaucoup d'entre vous l'ont probablement déjà remarqué, le concept d'IaC* n'a rien de nouveau, les gens essaient d'automatiser leurs déploiements sur le Cloud depuis plus d'une décennie, alors pourquoi Terraform est-il devenu si populaire ?
Pour faire simple, Terraform est un moteur de provisionnement de plateforme de cloud computing piloté par l'état. Il s'appuie sur des outils d'abstraction (connus sous le nom de fournisseurs et de backends) pour nous permettre d'écrire du code qui peut être interprété et traduit en appels CRUD API cohérents et déterministes, spécifiques au fournisseur de cloud, ce qui nous évite beaucoup de travail et de stress.

Vue macro du fonctionnement de Terraform

Infrastructure As Code

Bon, vous avez compris le principe de base, mais qu'est-ce que cela signifie réellement ?

L'IaC permet de résoudre les problèmes suivants :

  • Il n'est plus nécessaire d'avoir des équipes distinctes pour gérer l'approvisionnement de l'infrastructure et le développement du code de l'application.
  • Nous permet d'utiliser des outils modernes de contrôle des sources (tels que git) pour enregistrer, rédiger/réviser les changements apportés à notre infrastructure et nous fournit également une bonne vue d'ensemble de l'histoire/évolution de notre infrastructure.
  • Nous permet d'effectuer une intégration et un déploiement continus (CI/CD) de l'application et de l'infrastructure, ce qui signifie que les deux éléments peuvent être déployés main dans la main.
  • Nous permet de maintenir facilement plusieurs environnements en synchronisation sans avoir à effectuer des mises à jour manuelles.
  • Supprime le besoin de scripts et/ou d'outils de provisionnement d'infrastructure personnalisés construits en interne.
  • Réduit les erreurs humaines car les déploiements de code automatisés suppriment le facteur humain.

Il est important de noter que l'IaC n'est pas un nouveau concept, il existe en fait sous différentes formes depuis les tout premiers jours des plateformes de cloud computing (AWS avait CloudFormation et Azure avait ARM Templates).

Voici un exemple simple :

En tant que développeur de systèmes, j'ai réalisé que j'avais besoin d'un stockage sur le Cloud. Rien d'extraordinaire, mais j'ai besoin d'un endroit où déposer des fichiers et d'un endroit où lire des fichiers. Voyons à quoi cela ressemble conceptuellement lorsque l'on travaille avec Azure et une infrastructure de cloud "physique" :

Architecture conceptuelle du système

J'utilise ici la terminologie de Microsoft Azure, mais j'espère que ce n'est pas trop confus pour les personnes qui ne sont pas familières avec cette plateforme. Globalement, j'ai besoin d'un groupe de ressources (car dans Azure, les objets vivent dans des groupes de ressources), d'un compte de stockage et d'un conteneur de stockage. Avec toutes ces objets en place, je serai alors en mesure de stocker en toute sécurité mes fichiers à l'intérieur dudit conteneur dans le cloud 🙂 .
Maintenant, convertissons ce modèle conceptuel en Terraform HCL et voyons à quoi cela ressemble :

terraform {
  required_providers {
    azurerm = {
      source = "hashicorp/azurerm"
      version = "2.78.0"
    }
  }
}

provider "azuread" {
}
resource "azurerm_resource_group" "example" {
  name     = "example-resources"
  location = "West Europe"
}

resource "azurerm_storage_account" "example" {
  name                     = "examplestoracc"
  resource_group_name      = azurerm_resource_group.example.name
  location                 = azurerm_resource_group.example.location
  account_tier             = "Standard"
  account_replication_type = "LRS"
}

resource "azurerm_storage_container" "example" {
  name                  = "content"
  storage_account_name  = azurerm_storage_account.example.name
  container_access_type = "private"
}

Et si nous annotons notre dessin conceptuel avec la HCL, nous obtenons :

L'analyse détaillée

Je suis conscient que j'ai dit que je n'irais pas trop loin dans l'explication de la syntaxe de "HCL", mais je pense qu'une petite vue d'ensemble pourrait aider à expliquer les choses.
Reprenons notre exemple précédent de HCL pour notre compte de stockage, et décomposons-le étape par étape :

terraform {
  required_providers {
    azurerm = {
      source = "hashicorp/azurerm"
      version = "2.78.0"
    }
  }
}

backend "azurerm" {
  }
}
provider "azuread" {
}
resource "azurerm_resource_group" "example" {
  name     = "example-resources"
  location = "West Europe"
}
resource "azurerm_storage_account" "example" {
  name                     = "examplestoracc"
  resource_group_name      = azurerm_resource_group.example.name
  location                 = azurerm_resource_group.example.location
  account_tier             = "Standard"
  account_replication_type = "LRS"
}

En regardant cette syntaxe, vous pouvez facilement voir certaines similitudes avec des langages tels que JSON. Mais que signifie chaque partie (ou bloc) ?

terraform : Vous permet de configurer certains comportements de Terraform lui-même, comme les fournisseurs que vous souhaitez utiliser et les versions qu'il doit télécharger. N'oubliez pas : vous ne pouvez pas utiliser les ressources des fournisseurs sans indiquer au préalable à Terraform que vous souhaitez utiliser ces fournisseurs en particulier. Pour plus d'informations, consultez la documentation ici
backend: Permet de spécifier quel Backend nous voulons que Terraform utilise. Les backends déterminent deux choses essentielles : où notre état est stocké et où nos opérations sont exécutées. Essentiellement, si nous travaillons avec Azure et que nous voulons faire persister notre état dans le nuage également, nous pouvons le faire en utilisant le backend azurerm. Si nous ne spécifions pas de backend, alors celui par défaut est utilisé, souvent appelé local. Voir la documentation officielle ici
provider: Les Providers sont des plugins que Terraform utilise pour s'interfacer avec différents fournisseurs de cloud. Certains Providers vous permettent d'ajouter une configuration supplémentaire dans ces blocs. Voir les documents officiels ici
resource: Un mot clé dans HCL pour indiquer qu'il s'agit d'une ressource que vous voulez provisionner. Documentation officielle ici
"azure_reosurce_group": Il s'agit du "type" de la "ressource" que vous souhaitez. Lorsqu'il s'exécutera, Terraform essaiera de déterminer quel " fournisseur " contient ce " type " et exécutera la bonne action CRUD sur celui-ci.
"example": Il s'agit du nom/identifiant de cette ressource dans le script Terraform. Ne le confondez pas avec le nom de la ressource que vous verrez dans le portail Azure. Il est préférable de penser à cela de la même manière que vous auriez des noms de variables dans des langages de code tels que Go ou C#, etc. Remarquez que je peux appeler mes deux ressources avec le même identifiant "exemple", car Terraform autorise la duplication à condition que la combinaison du type de ressource et de l'identifiant soit unique.
name et location: Il s'agit d'attributs ou de propriétés de la "ressource". Ils déterminent la façon dont le "fournisseur" va approvisionner les choses dans le nuage. Si vous avez utilisé Azure, je suis sûr que vous savez que le nom et l'emplacement sont des éléments courants que vous définissez sur les ressources. Ici, le nom détermine le nom de la ressource que vous verrez dans le portail Azure.
resource_group_name = azurerm_resource_group.example.name: Ok, maintenant les choses deviennent intéressantes, c'est ici que la véritable puissance de Terraform commence à se manifester. Ici, nous passons la "sortie" d'une ressource dans une autre. Nous disons ici que l'attribut resource_group_name de notre azurerm_storage_account dépend de la sortie de l'azure_resource_group nommé example. Très astucieux, n'est-ce pas ?

Voilà qui vous donne un bon aperçu de la façon dont vous pouvez approvisionner des ressources et de la façon dont nous pouvons enchaîner la sortie d'une ressource à une autre. Ce " chaînage " de ressources est en fait un concept très important dans Terraform car il permet au moteur de construire son graphe de ressources. En définissant clairement les dépendances entre les ressources, on s'assure que le moteur sait qu'il doit les approvisionner dans le bon ordre (par exemple, il n'essaiera pas de faire les mêmes choses que les autres) : Il n'essaiera pas de provisionner le compte de stockage avant le groupe de ressources dans lequel il doit aller), et aidera Terraform à traduire les ressources dans son état.

Ce qu'il faut retenir ...

  • Terraform est un moteur piloté par l'état qui nous permet de fournir une infrastructure en nuage de manière simple et cohérente.
  • Terraform utilise un code connu sous le nom de HCL (Hashicorp Configuration Language).
  • Le HCL utilise le mot-clé resource pour définir les "ressources" que nous souhaitons voir provisionnées dans notre cloud.
  • Le HCL nous permet d'utiliser la configuration/sortie d'une ressource comme entrée pour la configuration/les attributs d'une autre ressource.
  • Terraform s'interface avec différentes technologies de Cloud à l'aide de Providers.
  • Lorsque Terraform s'exécute, il analyse les fichiers HCL et construit un graphe des ressources que nous souhaitons - connu sous le nom d'état souhaité.
  • En "reliant" les ressources entre elles, Terraform peut établir des dépendances explicites entre les objets de son graphe.
  • Terraform stocke la connaissance de toutes les ressources qu'il a provisionnées précédemment dans un fichier appelé State file.
  • Le contenu du fichier State est connu sous le nom de Perceived State - l'état dans lequel Terraform a laissé l'environnement la dernière fois qu'il a été exécuté à l'aide de nos fichiers HCL.
  • Terraform utilise des backends pour déterminer comment l'état doit être conservé.
  • Il existe de nombreux backends différents qui peuvent être utilisés en fonction du fournisseur de services cloud que nous utilisons et de la manière dont nous voulons que Terraform conserve l'état.
  • Lorsque Terraform veut approvisionner une ressource, et que cette ressource existe dans son état perçu, il interrogera le fournisseur de services en nuage pour déterminer l'état réel.
  • S'il existe des divergences entre l'état souhaité, l'état perçu et l'état réel, Terraform déterminera l'action corrective nécessaire pour que l'état réel corresponde à l'état souhaité.
  • Terraform comporte 3 étapes distinctes de cycle de vie : init, plan et apply.
  • Si vous renommez l'identifiant d'une ressource, Terraform agira comme s'il s'agissait d'une toute nouvelle ressource qu'il n'a jamais vue auparavant, et purgera tout ce qui concerne les ressources liées à l'ancien identifiant.

Walid ETTAYEB • 36 Articles

Passionné par l'informatique depuis mon plus jeune âge, je transforme ma passion en expertise.

View Articles