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: "<project_id>"
username: "<username>"
cloud:
project_id: <gcp_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
<project_id>
,<username>
,<gcp_project_id>
, 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=<key>
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 " <!DOCTYPE html> <html lang="fr"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>${upper(each.key)}</title> <style> body { background-color: ${each.value.color}; color: white; display: flex; justify-content: center; align-items: center; height: 100vh; margin: 0; font-family: Arial, sans-serif; } h1 { font-size: 5rem; } </style> </head> <body> <h1>${upper(each.key)}</h1> </body> </html>" > /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
Top comments (2)
Really like seeing projects that push for more open-source options. Makes me think- once you get deep into these setups, you ever actually want to go back to closed systems?
Hello and thank you for this very insightful comment. You've hit on a key point that many developers and DevOps engineers feel.
Once you've fully embraced open-source tools for tasks as critical as infrastructure management (IaC), the idea of going back to closed systems often becomes unthinkable. Several reasons explain this feeling:
With open source, there's no "black box." You can read the code, understand exactly how the tool works, and even fix it yourself in case of an urgent bug. This transparency builds a level of trust that a proprietary system can hardly match.
The Terraform/OpenTofu situation is a perfect example of freedom from vendor lock-in. Tying yourself to a closed system means accepting dependency on a single company's strategic, pricing, and licensing decisions. Open source, especially when governed by a neutral foundation like the Linux Foundation, guarantees the tool's longevity and freedom. You invest your time and skills in a standard that won't be privatized overnight.
Open-source projects benefit from collective intelligence. Features are often developed in response to the community's real needs, not solely for commercial reasons. You shift from being a simple "customer" to a potential "contributor" to a project you're passionate about.
That said, closed systems still have their advantages for certain organizations (dedicated support, highly integrated ecosystems, etc.). But for the engineer "on the ground," the freedom, flexibility, and collaborative philosophy of open source often create a one-way street.
Your comment perfectly summarizes why projects like OpenTofu aren't just technical alternatives, but fundamental movements driven by a community that values openness.