Introduction à OpenTofu pour les utilisateurs Terraform
OpenTofu est un fork communautaire de Terraform, compatible en grande partie avec ce dernier, mais qui prend une orientation technique différente sur certains points clés. Pour les utilisateurs expérimentés de Terraform, la transition vers OpenTofu est quasi transparente tout en offrant des fonctionnalités avancées comme le chiffrement natif de l'état ou une évaluation anticipée des expressions. Ce tutoriel illustre l'utilisation d'OpenTofu pour déployer une architecture répartie sur deux régions GCP avec deux machines virtuelles GCE faisant tourner NGINX, exposées via un Global Load Balancer. Le backend de stockage d'état utilisera GitLab comme source de vérité. Installation d'OpenTofu Installation Debian/Ubuntu : curl --proto '=https' --tlsv1.2 -fsSL https://get.opentofu.org/install-opentofu.sh | bash -s -- --install-method deb Pour vérifier la bonne installation de OpenTofu : tofu version Configuration du backend GitLab GitLab permet de stocker l'état via un repository en tant que backend "HTTP" compatible. Exemple terragrunt.hcl : locals { config = yamldecode(file("config.yaml")) gitlab_project_id = local.config.backend.gitlab.project_id gitlab_username = local.config.backend.gitlab.username gitlab_token = get_env("GITLAB_TOKEN", "") gitlab_path = "blog" gitlab_url = "https://gitlab.com/api/v4/projects/${local.gitlab_project_id}/terraform/state/${local.gitlab_path}" } generate "backend" { path = "backend.tf" if_exists = "overwrite_terragrunt" contents =

OpenTofu est un fork communautaire de Terraform, compatible en grande partie avec ce dernier, mais qui prend une orientation technique différente sur certains points clés. Pour les utilisateurs expérimentés de Terraform, la transition vers OpenTofu est quasi transparente tout en offrant des fonctionnalités avancées comme le chiffrement natif de l'état ou une évaluation anticipée des expressions.
Ce tutoriel illustre l'utilisation d'OpenTofu pour déployer une architecture répartie sur deux régions GCP avec deux machines virtuelles GCE faisant tourner NGINX, exposées via un Global Load Balancer. Le backend de stockage d'état utilisera GitLab comme source de vérité.
Installation d'OpenTofu
Installation Debian/Ubuntu :
curl --proto '=https' --tlsv1.2 -fsSL https://get.opentofu.org/install-opentofu.sh | bash -s -- --install-method deb
Pour vérifier la bonne installation de OpenTofu :
tofu version
Configuration du backend GitLab
GitLab permet de stocker l'état via un repository en tant que backend "HTTP" compatible.
Exemple terragrunt.hcl
:
locals {
config = yamldecode(file("config.yaml"))
gitlab_project_id = local.config.backend.gitlab.project_id
gitlab_username = local.config.backend.gitlab.username
gitlab_token = get_env("GITLAB_TOKEN", "")
gitlab_path = "blog"
gitlab_url = "https://gitlab.com/api/v4/projects/${local.gitlab_project_id}/terraform/state/${local.gitlab_path}"
}
generate "backend" {
path = "backend.tf"
if_exists = "overwrite_terragrunt"
contents = <<EOF
terraform {
backend "http" {
address = "${local.gitlab_url}"
lock_address = "${local.gitlab_url}/lock"
unlock_address = "${local.gitlab_url}/lock"
username = "${local.gitlab_username}"
password = "${local.gitlab_token}"
lock_method = "POST"
unlock_method = "DELETE"
retry_wait_min = 5
}
}
EOF
}
generate "providers" {
path = "providers.tf"
if_exists = "overwrite_terragrunt"
contents = <<EOF
provider "google" {
project = "${local.config.cloud.project_id}"
region = "${local.config.cloud.region}"
}
EOF
}
inputs = {
config = local.config
}
Ce module Terragrunt va charger un fichier config.yaml
de ce type :
backend:
gitlab:
project_id: ""
username: ""
cloud:
project_id:
region: europe-west9
workload:
france:
color: "#0000BB"
machine: e2-micro
region: europe-west9
traffic: 0.80
belgium:
color: "#BB0000"
machine: e2-micro
region: europe-west1
traffic: 0.20
Remplacez
,
,
, et les identifiants par les vôtres. Le projet doit être configuré pour permettre le remote backend via HTTP.
Pour pouvoir utiliser OpenTofu et le backend GitLab, il faut aussi exporter une variable d'environnement :
export GITLAB_TOKEN=
Infrastructure cible
- Deux instances GCE (dans
europe-west9
eteurope-west1
) avec NGINX - Global Load Balancer HTTP(S)
- Priorité pondérée sur les backends (ex : 80/20)
Exemple d’infrastructure (fichiers principaux)
workload.tf
resource "google_compute_instance" "nginx" {
for_each = var.config.cloud.workload
machine_type = each.value.machine
name = "nginx-${each.key}"
zone = "${each.value.region}-b"
boot_disk {
initialize_params {
image = "debian-cloud/debian-12"
}
}
network_interface {
network = "default"
access_config {}
}
tags = [ "public" ]
metadata_startup_script = <<-EOF
#!/bin/bash
apt-get update
apt-get install -y nginx
echo " ${upper(each.key)} ${upper(each.key)}
" > /var/www/html/index.nginx-debian.html
systemctl restart nginx
EOF
depends_on = [ google_project_service.apis ]
}
load_balancing.tf
resource "google_compute_instance_group" "group" {
for_each = var.config.cloud.workload
name = "group-${each.key}"
zone = "${each.value.region}-b"
instances = [google_compute_instance.nginx[each.key].self_link]
named_port {
name = "http"
port = 80
}
}
resource "google_compute_health_check" "default" {
name = "http-health-check"
check_interval_sec = 5
timeout_sec = 5
http_health_check {
port = 80
}
}
resource "google_compute_backend_service" "default" {
name = "nginx-backend"
load_balancing_scheme = "EXTERNAL"
port_name = "http"
protocol = "HTTP"
timeout_sec = 10
health_checks = [google_compute_health_check.default.self_link]
dynamic "backend" {
for_each = var.config.cloud.workload
content {
group = google_compute_instance_group.group[backend.key].self_link
balancing_mode = "UTILIZATION"
capacity_scaler = backend.value.traffic
}
}
}
resource "google_compute_url_map" "default" {
name = "url-map"
default_service = google_compute_backend_service.default.self_link
}
resource "google_compute_target_http_proxy" "default" {
name = "http-proxy"
url_map = google_compute_url_map.default.self_link
}
resource "google_compute_global_forwarding_rule" "default" {
name = "http-forwarding-rule"
target = google_compute_target_http_proxy.default.self_link
port_range = "80"
load_balancing_scheme = "EXTERNAL"
}
network.tf
resource "google_compute_firewall" "allow_http" {
name = "allow-http"
network = "default"
allow {
protocol = "tcp"
ports = ["80"]
}
source_ranges = ["0.0.0.0/0"]
target_tags = ["public"]
}
api.tf
resource "google_project_service" "apis" {
project = var.config.cloud.project_id
service = "compute.googleapis.com"
}
variables.tf
variable "config" {
type = any
}
Utilisation de Terragrunt avec OpenTofu
Terragrunt est pleinement compatible avec OpenTofu. Il suffit de remplacer la commande terraform
par tofu
dans votre via votre variable TERRAGRUNT_TFPATH :
export TERRAGRUNT_TFPATH=tofu
Conclusion
Ce projet démontre la maturité d'OpenTofu pour gérer des infrastructures complexes tout en restant compatible avec l'écosystème Terraform. Couplé à Terragrunt, il devient un outil de choix pour l'automatisation multi-environnement. L'intégration avec GitLab pour la gestion d'état et les pipelines CI renforce encore sa pertinence pour des workflows GitOps en production : il est tout aussi cpable que Terraform.
Grâce à une configuration modulaire, un backend distant sécurisé, et une exposition via un load balancer global, ce cas d’usage illustre comment industrialiser un déploiement cloud fiable avec des outils modernes, ouverts et maintenus par la communauté.
Références
- OpenTofu documentation : https://opentofu.org/docs/
- GitLab HTTP backend support : https://docs.gitlab.com/ee/user/infrastructure/terraform_backend.html
- GCP Terraform provider : https://registry.terraform.io/providers/hashicorp/google/latest/docs
- Terragrunt official site : https://terragrunt.gruntwork.io/
- Exemple Load Balancer GCP avec Terraform : https://cloud.google.com/load-balancing/docs/https/ext-https-lb-tf