TP 13 : OpenTofu - déployer un conteneur Nginx en local
Objectif
Section intitulée « Objectif »Tester OpenTofu sur un cas simple d’Infrastructure as Code :
- initialiser un projet OpenTofu
- installer un provider
- créer un conteneur Docker
- modifier une ressource
- observer le plan d’exécution
- supprimer les ressources créées
OpenTofu utilise la commande tofu. Les commandes principales sont similaires à Terraform : tofu init, tofu plan, tofu apply et tofu destroy. OpenTofu vise une compatibilité avec les configurations Terraform existantes, même si une migration doit être vérifiée au cas par cas.
Note : OpenTofu accepte le bloc
terraform {}par compatibilité ascendante avec Terraform. Dans un projet OpenTofu natif, il est possible d’utilisertofu {}à la place : les deux sont équivalents.
Prérequis
Section intitulée « Prérequis »Installer :
- OpenTofu
- Docker Desktop
- un éditeur de code, par exemple VS Code
Vérifier les installations :
tofu versiondocker versionArborescence du projet
Section intitulée « Arborescence du projet »tp-opentofu-docker/├── main.tf├── variables.tf├── outputs.tf└── .gitignoreFichier .gitignore
Section intitulée « Fichier .gitignore ».terraform/.opentofu/.terraform.lock.hcl*.tfstate*.tfstate.**.tfvarsOpenTofu utilise
.opentofu/comme répertoire de travail interne selon les versions. Les deux entrées sont nécessaires pour couvrir tous les cas.
Fichier main.tf
Section intitulée « Fichier main.tf »terraform { required_providers { docker = { source = "kreuzwerker/docker" version = "~> 3.0" } }}
provider "docker" {}
resource "docker_image" "nginx" { name = var.image_name}
resource "docker_container" "web" { name = var.container_name image = docker_image.nginx.image_id
ports { internal = 80 external = var.external_port }}OpenTofu utilise des providers pour interagir avec des systèmes externes. Les providers doivent être déclarés dans la configuration pour qu’OpenTofu puisse les installer et les utiliser.
Fichier variables.tf
Section intitulée « Fichier variables.tf »variable "image_name" { description = "Image Docker à utiliser" type = string default = "nginx:latest"}
variable "container_name" { description = "Nom du conteneur Docker" type = string default = "tp-opentofu-nginx"}
variable "external_port" { description = "Port exposé sur la machine locale" type = number default = 8080}Fichier outputs.tf
Section intitulée « Fichier outputs.tf »output "application_url" { description = "URL locale de l'application" value = "http://localhost:${var.external_port}"}
output "container_name" { description = "Nom du conteneur créé" value = docker_container.web.name}Étape 1 : initialiser le projet
Section intitulée « Étape 1 : initialiser le projet »Dans le dossier du TP :
tofu init
tofu initinitialise le dossier de travail et installe les plugins nécessaires aux providers déclarés.
Étape 2 : formater et valider
Section intitulée « Étape 2 : formater et valider »tofu fmttofu validateÉtape 3 : afficher le plan
Section intitulée « Étape 3 : afficher le plan »tofu plan
tofu planaffiche les actions qu’OpenTofu prévoit d’exécuter avant toute modification réelle de l’infrastructure.
Étape 4 : créer le conteneur
Section intitulée « Étape 4 : créer le conteneur »tofu applyConfirmer avec yes.
tofu applyexécute les actions prévues dans le plan pour créer, modifier ou supprimer l’infrastructure.
Tester ensuite dans le navigateur : http://localhost:8080
Ou avec curl :
curl http://localhost:8080Étape 5 : vérifier avec Docker
Section intitulée « Étape 5 : vérifier avec Docker »docker psLe conteneur doit apparaître avec le nom tp-opentofu-nginx.
Étape 6 : modifier une variable
Section intitulée « Étape 6 : modifier une variable »En pratique, on ne modifie pas les valeurs default dans variables.tf pour changer un paramètre : on utilise un fichier .tfvars. Créer un fichier dev.tfvars :
container_name = "tp-opentofu-nginx"external_port = 8081image_name = "nginx:latest"Puis exécuter :
tofu plan -var-file="dev.tfvars"Observer les changements proposés : OpenTofu doit indiquer que le conteneur sera recréé car le port change.
Appliquer :
tofu apply -var-file="dev.tfvars"Tester ensuite : http://localhost:8081
Bonne pratique : modifier les valeurs par défaut dans
variables.tfest réservé aux changements de valeurs référence du projet. Pour les environnements (dev, staging, prod), utiliser toujours des fichiers.tfvarsdistincts.
Étape 7 : observer le state
Section intitulée « Étape 7 : observer le state »Lister les ressources suivies par OpenTofu :
tofu state listAfficher le contenu détaillé d’une ressource :
tofu state show docker_container.webLe fichier de state permet à OpenTofu de suivre les ressources qu’il gère. Il ne doit pas être supprimé ou modifié manuellement sans raison précise.
Étape 8 : provoquer une dérive
Section intitulée « Étape 8 : provoquer une dérive »Supprimer manuellement le conteneur hors OpenTofu :
docker rm -f tp-opentofu-nginxAttention :
docker stopne suffit pas : OpenTofu ne gère pas l’état running/stopped d’un conteneur, uniquement son existence. Pour provoquer une vraie dérive détectable, il faut supprimer le conteneur avecdocker rm -f.
Puis relancer :
tofu planOpenTofu doit détecter que le conteneur n’existe plus et proposer de le recréer (+ create).
Rétablir l’état attendu :
tofu applyÉtape 9 : supprimer les ressources
Section intitulée « Étape 9 : supprimer les ressources »tofu destroyConfirmer avec yes.
tofu destroysupprime les objets gérés par la configuration OpenTofu courante.
Extension possible
Section intitulée « Extension possible »Ajouter un second conteneur avec une autre image, par exemple httpd:latest, exposé sur le port 8082 :
resource "docker_image" "httpd" { name = "httpd:latest"}
resource "docker_container" "apache" { name = "tp-opentofu-apache" image = docker_image.httpd.image_id
ports { internal = 80 external = 8082 }}Puis exécuter :
tofu plantofu apply