Aller au contenu

TP 13 : OpenTofu - déployer un conteneur Nginx en local

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’utiliser tofu {} à la place : les deux sont équivalents.

Installer :

Vérifier les installations :

Fenêtre de terminal
tofu version
docker version
tp-opentofu-docker/
├── main.tf
├── variables.tf
├── outputs.tf
└── .gitignore
.terraform/
.opentofu/
.terraform.lock.hcl
*.tfstate
*.tfstate.*
*.tfvars

OpenTofu utilise .opentofu/ comme répertoire de travail interne selon les versions. Les deux entrées sont nécessaires pour couvrir tous les cas.

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.

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
}
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
}

Dans le dossier du TP :

Fenêtre de terminal
tofu init

tofu init initialise le dossier de travail et installe les plugins nécessaires aux providers déclarés.

Fenêtre de terminal
tofu fmt
tofu validate
Fenêtre de terminal
tofu plan

tofu plan affiche les actions qu’OpenTofu prévoit d’exécuter avant toute modification réelle de l’infrastructure.

Fenêtre de terminal
tofu apply

Confirmer avec yes.

tofu apply exé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 :

Fenêtre de terminal
curl http://localhost:8080
Fenêtre de terminal
docker ps

Le conteneur doit apparaître avec le nom tp-opentofu-nginx.

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 = 8081
image_name = "nginx:latest"

Puis exécuter :

Fenêtre de terminal
tofu plan -var-file="dev.tfvars"

Observer les changements proposés : OpenTofu doit indiquer que le conteneur sera recréé car le port change.

Appliquer :

Fenêtre de terminal
tofu apply -var-file="dev.tfvars"

Tester ensuite : http://localhost:8081

Bonne pratique : modifier les valeurs par défaut dans variables.tf est réservé aux changements de valeurs référence du projet. Pour les environnements (dev, staging, prod), utiliser toujours des fichiers .tfvars distincts.

Lister les ressources suivies par OpenTofu :

Fenêtre de terminal
tofu state list

Afficher le contenu détaillé d’une ressource :

Fenêtre de terminal
tofu state show docker_container.web

Le 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.

Supprimer manuellement le conteneur hors OpenTofu :

Fenêtre de terminal
docker rm -f tp-opentofu-nginx

Attention : docker stop ne 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 avec docker rm -f.

Puis relancer :

Fenêtre de terminal
tofu plan

OpenTofu doit détecter que le conteneur n’existe plus et proposer de le recréer (+ create).

Rétablir l’état attendu :

Fenêtre de terminal
tofu apply
Fenêtre de terminal
tofu destroy

Confirmer avec yes.

tofu destroy supprime les objets gérés par la configuration OpenTofu courante.

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 :

Fenêtre de terminal
tofu plan
tofu apply