Une introduction à Terraform pour les débutants - Tutoriel Terraform
Qu'est-ce que Terraform et comment il révolutionne l'infrastructure cloud ?
L'expression "Infrastructure as Code" (IaC) est omniprésente dans l'univers DevOps. Elle désigne le processus de gestion et de déploiement de toute l'infrastructure informatique, qu'elle soit physique ou virtuelle, via des fichiers de configuration interprétables par des machines. C'est une transposition des pratiques d'ingénierie logicielle au domaine des opérations, permettant d'automatiser l'ensemble du centre de données par l'intermédiaire de scripts.
Malgré les avantages indéniables de l'IaC, certains défis persistent :
- La nécessité d'acquérir des compétences en codage.
- L'incertitude quant à l'impact réel des modifications.
- La difficulté de revenir en arrière après des changements.
- Le manque de visibilité sur l'historique des modifications.
- L'impossibilité d'automatiser certaines ressources.
- La gestion complexe d'environnements d'infrastructure multiples.
C'est dans ce contexte que Terraform a été conçu, afin de pallier ces difficultés.
Terraform : une solution IaC pour tous les clouds
Terraform est un outil open-source d'Infrastructure as Code, créé par HashiCorp. Il permet de définir et de déployer l'intégralité de l'infrastructure en utilisant un langage déclaratif intuitif.
Cet outil de provisionnement d'infrastructure vous permet de sauvegarder la configuration de votre infrastructure cloud sous forme de code. Il peut être comparé à des outils tels que CloudFormation, qui permet d'automatiser votre infrastructure AWS, mais avec une portée limitée à cette seule plateforme. Avec Terraform, l'automatisation de votre infrastructure est possible sur de nombreuses plateformes cloud.
Voici quelques-uns des avantages notables de l'utilisation de Terraform :
- Il offre une réelle orchestration, allant au-delà de la simple gestion de la configuration.
- Il est compatible avec une multitude de fournisseurs comme AWS, Azure, GCP, DigitalOcean, et bien d'autres.
- Il assure une infrastructure immuable, où la configuration est modifiée progressivement et sans interruption.
- Il utilise HCL (HashiCorp Configuration Language), un langage de configuration facile à appréhender.
- Il facilite la migration vers différents fournisseurs.
- Il prend en charge une architecture client, éliminant le besoin d'une gestion de configuration supplémentaire sur un serveur.
Comprendre les concepts clés de Terraform
Voici les concepts et terminologies essentiels à connaître pour utiliser Terraform :
- Variables : Également appelées variables d'entrée, il s'agit de paires clé-valeur permettant la personnalisation des modules Terraform.
- Fournisseur : Plugin servant d'interface avec les API de service et donnant accès à leurs ressources associées.
- Module : Dossier contenant les modèles Terraform où sont définies toutes les configurations.
- État : Informations mises en cache concernant l'infrastructure gérée par Terraform et ses configurations.
- Ressources : Ensemble d'un ou plusieurs objets d'infrastructure (instances de calcul, réseaux virtuels, etc.) utilisés pour la configuration et la gestion de l'infrastructure.
- Source de données : Implémentée par les fournisseurs pour obtenir des informations sur les objets externes à Terraform.
- Valeurs de sortie : Valeurs retournées par un module Terraform, utilisables dans d'autres configurations.
- Planifier : Étape où Terraform détermine les actions nécessaires (création, mise à jour, suppression) pour aligner l'état réel de l'infrastructure avec l'état désiré.
- Appliquer : Étape où Terraform met en œuvre les changements définis dans le plan pour transformer l'état réel de l'infrastructure en l'état souhaité.
Le cycle de vie de Terraform
Le cycle de vie de Terraform se déroule en quatre étapes principales : initialisation, planification, application et destruction.
- Terraform init : Initialise le répertoire de travail, qui contient tous les fichiers de configuration.
- Terraform plan : Crée un plan d'exécution pour atteindre l'état souhaité de l'infrastructure, en fonction des modifications apportées aux fichiers de configuration.
- Terraform apply : Applique les modifications définies dans le plan pour que l'infrastructure corresponde à l'état souhaité.
- Terraform destroy : Supprime toutes les anciennes ressources d'infrastructure qui ont été modifiées après l'application.
Comment fonctionne Terraform ?
L'architecture de Terraform repose sur deux composantes essentielles :

Le cœur de Terraform
Le cœur de Terraform utilise deux types de sources d'entrée :
Premièrement, la configuration Terraform que vous, en tant qu'utilisateur, définissez. C'est ici que vous spécifiez ce qui doit être créé ou provisionné. Deuxièmement, l'état dans lequel Terraform conserve une version à jour de la configuration actuelle de l'infrastructure.
Le cœur de Terraform analyse ces informations pour déterminer le plan d'action. Il compare l'état actuel de l'infrastructure avec la configuration souhaitée et détermine les opérations nécessaires (création, mise à jour, suppression) pour atteindre l'état final.
Les fournisseurs
La seconde composante de l'architecture de Terraform est constituée de fournisseurs spécifiques à différentes technologies. Il peut s'agir de fournisseurs de cloud comme AWS, Azure, GCP, ou d'autres infrastructures en tant que plateforme. On trouve également des fournisseurs de composants de plus haut niveau, comme Kubernetes, ou encore des outils en SaaS.
Cette approche offre la possibilité de créer une infrastructure à différents niveaux.
Par exemple, vous pouvez commencer par créer l'infrastructure de base AWS, puis déployer Kubernetes dessus, et enfin configurer des services à l'intérieur de ce cluster Kubernetes.
Terraform propose plus d'une centaine de fournisseurs différents, donnant accès à des ressources spécifiques. Par exemple, avec le fournisseur AWS, vous pouvez accéder à des centaines de ressources comme les instances EC2 ou les utilisateurs AWS. De même, le fournisseur Kubernetes vous permet de gérer des services, des déploiements et des espaces de noms.
Terraform s'efforce ainsi de couvrir l'ensemble de la configuration de votre application, de l'infrastructure jusqu'à l'application elle-même.
Passons à des exemples pratiques !
Nous allons installer Terraform sur Ubuntu et créer une infrastructure très simple.
Installation de Terraform
Commencez par télécharger le dernier package de Terraform.
Consultez la page de téléchargement officielle pour obtenir la dernière version pour votre système d'exploitation.
[email protected]:~$ wget https://releases.hashicorp.com/terraform/0.13.0/terraform_0.13.0_linux_amd64.zip
--2020-08-14 16:55:38-- https://releases.hashicorp.com/terraform/0.13.0/terraform_0.13.0_linux_amd64.zip
Résolution de releases.hashicorp.com (releases.hashicorp.com)… 151.101.153.183, 2a04:4e42:24::439
Connexion à releases.hashicorp.com (releases.hashicorp.com)|151.101.153.183|:443… connecté.
Requête HTTP transmise, en attente de la réponse… 200 OK
Longueur : 34851622 (33M) [application/zip]
Enregistrement dans : « terraform_0.13.0_linux_amd64.zip »
terraform_0.13.0_linux_amd64.zip 100%[==================================================>] 33,24M 90,3KB/s dans 5m 28s
2020-08-14 17:01:06 (104 KB/s) - « terraform_0.13.0_linux_amd64.zip » enregistré [34851622/34851622]
Décompressez ensuite le package téléchargé.
[email protected]:~$ unzip terraform_0.13.0_linux_amd64.zip
Archive : terraform_0.13.0_linux_amd64.zip
gonflement : terraform
Déplacez l'exécutable Terraform dans le chemin indiqué ci-dessous et vérifiez la version installée.
[email protected]:~$ sudo mv terraform /usr/local/bin/
[sudo] mot de passe de toptips.fr :
[email protected]:~$ terraform -v
Terraform v0.13.0
Vous pouvez désormais visualiser les commandes disponibles pour l'exécution.
[email protected]:~$ terraform
Usage: terraform [-version] [-help] <commande> [args]
Les commandes disponibles pour l'exécution sont listées ci-dessous.
Les commandes les plus courantes et utiles sont affichées en premier, suivies
des commandes moins courantes ou plus avancées. Si vous débutez avec
Terraform, commencez par les commandes courantes. Pour les
autres commandes, veuillez lire l'aide et la documentation avant de les utiliser.
Commandes courantes :
apply Construit ou modifie l'infrastructure
console Console interactive pour les interpolations Terraform
destroy Détruit l'infrastructure gérée par Terraform
env Gestion de l'espace de travail
fmt Réécrit les fichiers de configuration au format canonique
get Télécharge et installe les modules pour la configuration
graph Crée un graphique visuel des ressources Terraform
import Importe l'infrastructure existante dans Terraform
init Initialise un répertoire de travail Terraform
login Obtient et enregistre les informations d'identification d'un hôte distant
logout Supprime les informations d'identification stockées localement pour un hôte distant
output Lit une sortie d'un fichier d'état
plan Génère et affiche un plan d'exécution
providers Affiche une arborescence des fournisseurs utilisés dans la configuration
refresh Met à jour le fichier d'état local en fonction des ressources réelles
show Inspecte l'état ou le plan Terraform
taint Marque manuellement une ressource pour une recréation
untaint Démarque manuellement une ressource comme étant corrompue
validate Valide les fichiers Terraform
version Affiche la version Terraform
workspace Gestion de l'espace de travail
Toutes les autres commandes :
0.12upgrade Réécrit le code source de module pré-0.12 pour v0.12
0.13upgrade Réécrit le code source de module pré-0.13 pour v0.13
debug Gestion de la sortie de débogage (expérimental)
force-unlock Déverrouille manuellement l'état Terraform
push Commande obsolète pour Terraform Enterprise legacy (v1)
state Gestion avancée de l'état
Provisionnement d'une instance AWS EC2 avec Terraform
Pour cette démonstration, nous allons lancer une nouvelle instance AWS EC2 en utilisant Terraform.
Créez un répertoire de travail pour cette démonstration.
[email protected]:~$ mkdir terraform_demo
Accédez à ce répertoire et créez un fichier de configuration Terraform, dans lequel vous définirez le fournisseur et les ressources nécessaires au lancement d'une instance AWS EC2.
[email protected]:~$ cd terraform_demo/
[email protected]:~/terraform_demo$ gedit awsec2.tf
provider "aws" {
access_key = "B5KG6Fe5GUKIATUF5UD"
secret_key = "R4gb65y56GBF6765ejYSJA4YtaZ+T6GY7H"
region = "us-west-2"
}
resource "aws_instance" "terraform_demo" {
ami = "ami-0a634ae95e11c6f91"
instance_type = "t2.micro"
}
Note : J'ai modifié les clés d'accès et secrètes 😛. Vous devez utiliser les vôtres.
Dans cette configuration, nous spécifions le fournisseur comme étant AWS. Nous y indiquons également les informations d'identification de l'utilisateur AWS et les régions où l'instance doit être lancée.
Dans la section `resources`, nous définissons l'AMI d'Ubuntu (ami-0a634ae95e11c6f91) et le type d'instance, `t2.micro`.
Comme vous pouvez le constater, le fichier de configuration est facile à lire et à comprendre, même si vous n'êtes pas un expert en codage.
Initialisation de Terraform
La première étape consiste à initialiser Terraform.
[email protected]:~/terraform_demo$ terraform init
Initializing the backend...
Initializing provider plugins...
- Using previously-installed hashicorp/aws v3.2.0
The following providers do not have any version constraints in configuration,
so the latest version was installed.
To prevent automatic upgrades to new major versions that may contain breaking
changes, we recommend adding version constraints in a required_providers block
in your configuration, with the constraint strings suggested below.
* hashicorp/aws: version = "~> 3.2.0"
Terraform has been successfully initialized!
You may now begin working with Terraform. Try running "terraform plan" to see
any changes that are required for your infrastructure. All Terraform commands
should now work.
If you ever set or change modules or backend configuration for Terraform,
rerun this command to reinitialize your working directory. If you forget, other
commands will detect it and remind you to do so if necessary.
Planification de Terraform
Vient ensuite l'étape de la planification. Terraform génère un graphique d'exécution pour créer et provisionner l'infrastructure.
[email protected]:~/terraform_demo$ terraform plan
Refreshing Terraform state in-memory prior to plan...
The refreshed state will be used to calculate this plan, but will not be
persisted to local or remote state storage.
------------------------------------------------------------------------
An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
+ create
Terraform will perform the following actions:
# aws_instance.terraform_demo will be created
+ resource "aws_instance" "terraform_demo" {
+ ami = "ami-0a634ae95e11c6f91"
+ arn = (known after apply)
+ associate_public_ip_address = (known after apply)
+ availability_zone = (known after apply)
+ cpu_core_count = (known after apply)
+ cpu_threads_per_core = (known after apply)
+ get_password_data = false
+ host_id = (known after apply)
+ id = (known after apply)
+ instance_state = (known after apply)
+ instance_type = "t2.micro"
+ ipv6_address_count = (known after apply)
+ ipv6_addresses = (known after apply)
+ key_name = (known after apply)
+ outpost_arn = (known after apply)
+ password_data = (known after apply)
+ placement_group = (known after apply)
+ primary_network_interface_id = (known after apply)
+ private_dns = (known after apply)
+ private_ip = (known after apply)
+ public_dns = (known after apply)
+ public_ip = (known after apply)
+ secondary_private_ips = (known after apply)
+ security_groups = (known after apply)
+ source_dest_check = true
+ subnet_id = (known after apply)
+ tenancy = (known after apply)
+ volume_tags = (known after apply)
+ vpc_security_group_ids = (known after apply)
+ ebs_block_device {
+ delete_on_termination = (known after apply)
+ device_name = (known after apply)
+ encrypted = (known after apply)
+ iops = (known after apply)
+ kms_key_id = (known after apply)
+ snapshot_id = (known after apply)
+ volume_id = (known after apply)
+ volume_size = (known after apply)
+ volume_type = (known after apply)
}
+ ephemeral_block_device {
+ device_name = (known after apply)
+ no_device = (known after apply)
+ virtual_name= (known after apply)
}
+ metadata_options {
+ http_endpoint = (known after apply)
+ http_put_response_hop_limit = (known after apply)
+ http_tokens = (known after apply)
}
+ network_interface {
+ delete_on_termination = (known after apply)
+ device_index = (known after apply)
+ network_interface_id = (known after apply)
}
+ root_block_device {
+ delete_on_termination = (known after apply)
+ device_name = (known after apply)
+ encrypted = (known after apply)
+ iops = (known after apply)
+ kms_key_id = (known after apply)
+ volume_id = (known after apply)
+ volume_size = (known after apply)
+ volume_type = (known after apply)
}
}
Plan: 1 to add, 0 to change, 0 to destroy.
------------------------------------------------------------------------
Note: You didn't specify an "-out" parameter to save this plan, so Terraform
can't guarantee that exactly these actions will be performed if
"terraform apply" is subsequently run.
Application de Terraform
L'étape d'application exécutera le fichier de configuration et lancera une instance AWS EC2. Lors de l'exécution de la commande `apply`, il vous sera demandé "Voulez-vous effectuer ces actions ?". Répondez par "yes" et appuyez sur Entrée.
[email protected]:~/terraform_demo$ terraform apply
An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
+ create
Terraform will perform the following actions:
# aws_instance.terraform_demo will be created
+ resource "aws_instance" "terraform_demo" {
+ ami = "ami-0a634ae95e11c6f91"
+ arn = (known after apply)
+ associate_public_ip_address = (known after apply)
+ availability_zone = (known after apply)
+ cpu_core_count = (known after apply)
+ cpu_threads_per_core = (known after apply)
+ get_password_data = false
+ host_id = (known after apply)
+ id = (known after apply)
+ instance_state = (known after apply)
+ instance_type = "t2.micro"
+ ipv6_address_count = (known after apply)
+ ipv6_addresses = (known after apply)
+ key_name = (known after apply)
+ outpost_arn = (known after apply)
+ password_data = (known after apply)
+ placement_group = (known after apply)
+ primary_network_interface_id = (known after apply)
+ private_dns = (known after apply)
+ private_ip = (known after apply)
+ public_dns = (known after apply)
+ public_ip = (known after apply)
+ secondary_private_ips = (known after apply)
+ security_groups = (known after apply)
+ source_dest_check = true
+ subnet_id = (known after apply)
+ tenancy = (known after apply)
+ volume_tags = (known after apply)
+ vpc_security_group_ids = (known after apply)
+ ebs_block_device {
+ delete_on_termination = (known after apply)
+ device_name = (known after apply)
+ encrypted = (known after apply)
+ iops = (known after apply)
+ kms_key_id = (known after apply)
+ snapshot_id = (known after apply)
+ volume_id = (known after apply)
+ volume_size = (known after apply)
+ volume_type = (known after apply)
}
+ ephemeral_block_device {
+ device_name = (known after apply)
+ no_device = (known after apply)
+ virtual_name= (known after apply)
}
+ metadata_options {
+ http_endpoint = (known after apply)
+ http_put_response_hop_limit = (known after apply)
+ http_tokens = (known after apply)
}
+ network_interface {
+ delete_on_termination = (known after apply)
+ device_index = (known after apply)
+ network_interface_id = (known after apply)
}
+ root_block_device {
+ delete_on_termination = (known after apply)
+ device_name = (known after apply)
+ encrypted = (known after apply)
+ iops = (known after apply)
+ kms_key_id = (known after apply)
+ volume_id = (known after apply)
+ volume_size = (known after apply)
+ volume_type = (known after apply)
}
}
Plan: 1 to add, 0 to change, 0 to destroy.
Do you want to perform these actions?
Terraform will perform the actions described above.
Only 'yes' will be accepted to approve.
Enter a value: yes
aws_instance.terraform_demo: Creating...
aws_instance.terraform_demo: Still creating... [10s elapsed]
aws_instance.terraform_demo: Still creating... [20s elapsed]
aws_instance.terraform_demo: Still creating... [30s elapsed]
aws_instance.terraform_demo: Still creating... [40s elapsed]
aws_instance.terraform_demo: Creation complete after 44s [id=i-0eec33286ea4b0740]
Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
Accédez à votre tableau de bord AWS EC2 et vous constaterez qu'une nouvelle instance a été créée, avec l'identifiant mentionné à la fin de la commande `apply`.

Vous avez réussi à lancer une instance AWS EC2 à l'aide de Terraform.
Destruction de l'infrastructure avec Terraform
Enfin, si vous souhaitez supprimer l'infrastructure, utilisez la commande `destroy`.
[email protected]:~/terraform_demo$ terraform destroy
aws_instance.terraform_demo: Refreshing state... [id=i-0eec33286ea4b0740]
An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
- destroy
Terraform will perform the following actions:
# aws_instance.terraform_demo will be destroyed
- resource "aws_instance" "terraform_demo" {
- ami = "ami-0a634ae95e11c6f91" -> null
- arn = "arn:aws:ec2:us-west-2:259212389929:instance/i-0eec33286ea4b0740" -> null
- associate_public_ip_address = true -> null
- availability_zone = "us-west-2c" -> null
- cpu_core_count = 1 -> null
- cpu_threads_per_core = 1 -> null
- disable_api_termination = false -> null
- ebs_optimized = false -> null
- get_password_data = false -> null
- hibernation = false -> null
- id = "i-0eec33286ea4b0740" -> null
- instance_state = "running" -> null
- instance_type = "t2.micro" -> null
- ipv6_address_count = 0 -> null
- ipv6_addresses = [] -> null
- monitoring = false -> null
- primary_network_interface_id = "eni-02a46f2802fd15634" -> null
- private_dns = "ip-172-31-13-160.us-west-2.compute.internal" -> null
- private_ip = "172.31.13.160" -> null
- public_dns = "ec2-34-221-77-94.us-west-2.compute.amazonaws.com" -> null
- public_ip = "34.221.77.94" -> null
- secondary_private_ips = [] -> null
- security_groups = [
- "default",
] -> null
- source_dest_check = true -> null
- subnet_id = "subnet-5551200c" -> null
- tags = {} -> null
- tenancy = "default" -> null
- volume_tags = {} -> null
- vpc_security_group_ids = [
- "sg-b5b480d1",
] -> null
- credit_specification {
- cpu_credits = "standard" -> null
}
- metadata_options {
- http_endpoint = "enabled" -> null
- http_put_response_hop_limit = 1 -> null
- http_tokens = "optional" -> null
}
- root_block_device {
- delete_on_termination = true -> null
- device_name = "/dev/sda1" -> null
- encrypted = false -> null
- iops = 100 -> null
- volume_id = "vol-0be2673afff6b1a86" -> null
- volume_size = 8 -> null
- volume_type = "gp2" -> null
}
}
Plan: 0 to add, 0 to change, 1 to destroy.
Do you really want to destroy all resources?
Terraform will destroy all your managed infrastructure, as shown above.
There is no undo. Only 'yes' will be accepted to confirm.
Enter a value: yes
aws_instance.terraform_demo: Destroying... [id=i-0eec33286ea4b0740]
aws_instance.terraform_demo: Still destroying... [id=i-0eec33286ea4b0740, 10s elapsed]
aws_instance.terraform_demo: Still destroying... [id=i-0eec33286ea4b0740, 20s elapsed]
aws_instance.terraform_demo: Still destroying... [id=i-0eec33286ea4b0740, 30s elapsed]
aws_instance.terraform_demo: Destruction complete after 34s
Destroy complete! Resources: 1 destroyed.
Si vous vérifiez de nouveau le tableau de bord EC2, vous constaterez que l'instance a été résiliée.

Conclusion
Cet article vous a donné un aperçu de ce que vous pouvez réaliser avec Terraform. N'hésitez pas à essayer l'exemple que nous avons abordé ensemble.
Vous pourriez également être intéressé par ces autres solutions d'automatisation d'infrastructure.
Si vous souhaitez approfondir vos connaissances, je vous recommande de consulter ce cours sur l'apprentissage de DevOps avec Terraform.