IaC Terraform

1. Terraform

Terraform est la solution Infrastructure as Code de HashiCorp : un outil déclaratif pour construire, modifier et gérer l’infrastructure d’une manière sûre et reproductible. Les opérateurs et les équipes d’infrastructure peuvent utiliser Terraform pour gérer les environnements avec un langage de configuration appelé HashiCorp Configuration Language (HCL) pour des déploiements automatisés lisibles par l’homme.

2. Infrastructure as Code

L’infrastructure as code est un processus de gestion de l’infrastructure avec un ou plusieurs fichiers plutôt que de configurer manuellement les ressources dans une interface utilisateur. Une ressource dans ce cas est tout élément d’infrastructure dans un environnement donné, tel qu’une machine virtuelle, un groupe de sécurité, une interface réseau, etc.

À un haut niveau, Terraform permet aux opérateurs d’utiliser HCL pour créer des fichiers contenant les définitions de leurs ressources désirées chez presque tous les fournisseurs (AWS, GCP, GitHub, Docker, etc.) et automatise la création de ces ressources au moment de leur application.

3. Avantages de Terraform

Bien que plusieurs solutions actuelles d’infrastructure as code puissent fonctionner dans votre environnement, Terraform vise à offrir quelques avantages aux exploitants et aux organisations de toute taille :

  • Gestion d’environnement hétérogène (platoform agnostic)
  • Gestion des états
  • Confiance en l’opérateur

3.1. Gestion d’environnement hétérogène (platoform agnostic)

Dans un centre de données moderne, vous pouvez disposer de plusieurs nuages et plates-formes différents pour prendre en charge vos diverses applications. Avec Terraform, vous pouvez gérer un environnement hétérogène avec le même workflow en créant un fichier de configuration pour répondre aux besoins de votre projet ou de votre organisation.

3.2. Gestion des états

Terraform crée un fichier d’état lors de la première initialisation d’un projet. Terraform utilise cet état local pour créer des plans et apporter des modifications à votre infrastructure. Avant toute opération, Terraform effectue un rafraîchissement pour mettre à jour l’état avec l’infrastructure réelle. Cela signifie que l’état de Terraform est la source de vérité par laquelle les changements de configuration sont mesurés. Si un changement est effectué ou si une ressource est ajoutée à une configuration, Terraform compare ces changements avec le fichier d’état pour déterminer quels changements entraînent une nouvelle ressource ou des modifications de ressources.

3.3. Confiance en l’opérateur

Le workflow intégré à Terraform vise à inspirer confiance aux utilisateurs en favorisant des opérations facilement répétables et une phase de planification permettant aux utilisateurs de s’assurer que les actions entreprises par Terraform ne causeront pas de perturbation dans leur environnement. Lors de l’application de Terraform, l’utilisateur sera invité à examiner les changements proposés et devra les confirmer, sinon Terraform n’appliquera pas le plan proposé.

4. Concepts terraform

Le langague HCL (HCL is the HashiCorp configuration language.) déclare des blocs d’objets qui sont mis en relation dans un ou plusieurs fichiers.

4.1. Ressource

Une ressource est par exemple aws_vpc, aws_db_instance, etc. Une ressource appartient à un fournisseur (provider), accepte des arguments, produit des attributs, a des cycles de vie. La ressource peut être créée, récupérée, mise à jour et supprimée.

4.2. Module de ressource

Un module de ressources est une collection de ressources connectées qui, ensemble, effectuent une action commune (par exemple, le module AWS VPC Terraform crée des VPC, des sous-réseaux, une passerelle NAT, etc). ). Il dépend de la configuration du fournisseur, qui peut être définie dans ce module, ou dans des structures de niveau supérieur (par exemple, dans un module d’infrastructure).

4.3. Module d’infrastructure

Un module d’infrastructure est un ensemble de modules de ressources, qui peuvent logiquement ne pas être connectés, mais qui, dans la situation/le projet/la configuration actuelle, servent le même objectif. Il définit la configuration pour les fournisseurs, qui est transmise aux modules de ressources en aval et aux ressources. Il est normalement limité pour travailler dans une entité par séparateur logique (par exemple, Région AWS, Google Project). Un exemple est terraform-aws-atlantis qui utilise des modules de ressources comme terraform-aws-vpc et terraform-aws-security-group pour créer l’infrastructure nécessaire à l’exécution d’Atlantis sur AWS Fargate.

4.4. Composition

Une composition est un ensemble de modules d’infrastructure, qui peuvent s’étendre sur plusieurs zones logiquement séparées (p. ex. régions AWS), plusieurs comptes AWS). Une composition est utilisée pour décrire l’infrastructure complète requise pour l’ensemble de l’organisation ou du projet. Une composition est constituée de modules d’infrastructure, qui sont des modules de ressources, qui mettent en œuvre des ressources individuelles.

4.5. Source des données (Data source)

Une source de données (Data source) effectue une opération en lecture seule et dépend de la configuration du fournisseur, elle est utilisée dans un module de ressources et un module d’infrastructure. La source de données terraform_remote_state agit comme une agglomérant pour les modules et les compositions de niveau supérieur.

Une source de données externe permet à un programme externe d’agir comme une source de données, exposant des données arbitraires pour une utilisation ailleurs dans la configuration de Terraform. La source de données http fait une requête HTTP GET à l’URL donnée et exporte des informations sur la réponse, ce qui est souvent utile pour obtenir des informations à partir de points d’extrémité où le fournisseur Terraform natif n’existe pas.

4.6. État distant (Remote state)

Les modules et les compositions d’infrastructure doivent persister dans leur état dans un endroit distant qui peut être atteint par d’autres de manière contrôlable (ACL, versioning, logging).

4.7. Fournisseur (Provider)

Bien que les ressources soient la construction principale dans le langage Terraform, les comportements des ressources dépendent des types de ressources qui leur sont associés, et ces types sont définis par les fournisseurs.

Chaque fournisseur offre un ensemble de types de ressources nommés et définit pour chaque type de ressource les arguments qu’il accepte, les attributs qu’il exporte et la manière dont les modifications apportées aux ressources de ce type sont réellement appliquées aux API distantes.

La plupart des fournisseurs disponibles correspondent à une plate-forme d’infrastructure cloud ou sur site, et proposent des types de ressources correspondant à chacune des caractéristiques de cette plate-forme.

Les fournisseurs ont généralement besoin d’une configuration propre pour spécifier les URL des points d’extrémité, les régions, les paramètres d’authentification, etc. Tous les types de ressources appartenant au même fournisseur partageront la même configuration, ce qui évitera de devoir répéter ces informations communes dans chaque déclaration de ressources.

4.8. Provisionneur

Les provisionneurs peuvent être utilisés pour modéliser des actions spécifiques sur la machine locale ou sur une machine distante afin de préparer des serveurs ou d’autres objets d’infrastructure pour le service.

Terraform inclut le concept de provisionneurs comme mesure de pragmatisme, sachant qu’il y aura toujours certains comportements qui ne pourront pas être directement représentés dans le modèle déclaratif de Terraform.

4.9. Quelle est la difficulté ?

Alors que les ressources individuelles sont comme des atomes dans l’infrastructure, les modules de ressources sont des molécules. Le module est une plus petite unité versionnée et partageable. Il a une liste exacte d’arguments, implémente une logique de base pour qu’une telle unité puisse remplir les fonctions requises. Par exemple, terraform-aws-security-group crée des ressources aws_security_group et aws_security_group_list en fonction des entrées. Ce module de ressources seul peut être utilisé avec d’autres modules pour créer un module d’infrastructure.

L’accès aux données à travers les molécules (modules de ressources et modules d’infrastructure) est effectué en utilisant les sorties (module) et les sources de données.

L’accès entre les compositions est effectué en utilisant des sources de données d’état distantes. En mettant les concepts décrits ci-dessus en pseudo-relations, cela peut ressembler à ceci :

composition-1 {
  infrastructure-module-1 {
    data-source-1 => d1

    resource-module-1 {
      data-source-2 => d2
      resource-1 (d1, d2)
      resource-2 (d2)
    }

    resource-module-2 {
      data-source-3 => d3
      resource-3 (d1, d3)
      resource-4 (d3)
    }
  }

}

4.10. Fichiers Terraform

Ces descriptions sont écrites dans des fichiers *.tf.

On applique terraform pour différentes action : plan, apply, destroy, …

Pour les petites configuration on placera tout dans un seul fichier. On prendra toutefois l’habitude de diviser sa configuration en fichiers distincts, comme par exemple1 :

  • main.tf
  • outputs.tf
  • terraform.tfvars
  • variables.tf

4.11. Syntaxe HCL

resource "aws_vpc" "main" {
  cidr_block = var.base_cidr_block
}

<BLOCK TYPE> "<BLOCK LABEL>" "<BLOCK LABEL>" {
  # Block body
  <IDENTIFIER> = <EXPRESSION> # Argument
}
  • Les blocs sont des conteneurs pour d’autres contenus et représentent généralement la configuration d’un certain type d’objet, comme une ressource (<BLOCK TYPE>). Les blocs ont un type de bloc (<BLOCK TYPE>), peuvent avoir zéro ou plusieurs étiquettes ("<BLOCK LABEL>"), et ont un corps qui contient un nombre quelconque d’arguments (<IDENTIFIER> = <EXPRESSION>) et de blocs imbriqués. La plupart des fonctionnalités de Terraform sont contrôlées par des blocs de niveau supérieur dans un fichier de configuration.
  • Les arguments attribuent une valeur (<EXPRESSION>) à un nom (<IDENTIFIER>). Ils apparaissent à l’intérieur des blocs.
  • Les expressions représentent une valeur, soit littéralement, soit en référençant et en combinant d’autres valeurs. Elles apparaissent comme des valeurs pour les arguments, ou dans d’autres expressions.