Exercice 04 : Contrôler le cycle de vie des ressources
🎯 Objectifs
À la fin de cet exercice, vous serez capable de :
- ✅ Protéger une ressource contre la destruction avec
prevent_destroy - ✅ Remplacer une ressource sans coupure avec
create_before_destroy - ✅ Ignorer des changements sur des attributs spécifiques avec
ignore_changes - ✅ Forcer le remplacement d'une ressource avec
replace_triggered_by
Durée estimée : 20 minutes
Difficulté : ⭐⭐⭐⭐☆ (Avancé)
Prérequis : Terraform installé, exercices avancés 01-03 terminés
📖 Contexte
Par défaut, Terraform détruit et recrée les ressources quand certains attributs changent. Le bloc lifecycle {} permet de modifier ce comportement : protéger contre la destruction accidentelle, réduire les temps d'arrêt, ou ignorer les changements gérés par d'autres outils (scripts, opérateurs humains).
📋 Énoncé
Vous allez configurer différentes stratégies lifecycle sur des conteneurs Docker pour simuler les besoins de production : protection contre la destruction, remplacement sans coupure, et ignorer les modifications manuelles.
Résultat attendu :
- Compréhension pratique des 4 options lifecycle
- Configuration production-ready avec prevent_destroy et create_before_destroy
🧭 Déroulement de l'exercice
Tâche 1 : Protéger avec prevent_destroy
Créez un conteneur avec lifecycle { prevent_destroy = true } et essayez de le détruire.
Indice :
terraform destroyou une configuration qui force le remplacement retournera une erreur :Error: Instance cannot be destroyed.
Vérification : terraform destroy échoue avec le message prevent_destroy sur la ressource protégée.
Tâche 2 : Remplacement sans coupure avec create_before_destroy
Configurez un conteneur avec lifecycle { create_before_destroy = true } et changez un attribut qui force le remplacement (ex: le name).
Indice : Par défaut : détruire d'abord → recréer (coupure). Avec
create_before_destroy: créer d'abord → détruire l'ancien (pas de coupure).
Vérification : terraform plan affiche +/- au lieu de -/+ pour la ressource.
Tâche 3 : Ignorer des changements avec ignore_changes
Créez un conteneur avec lifecycle { ignore_changes = [labels] }, puis modifiez manuellement les labels dans Docker. Observez que Terraform ne propose pas de revert.
Indice :
ignore_changesprend une liste d'attributs à ignorer.ignore_changes = allignore tous les changements (cas extrême).
Vérification : terraform plan affiche No changes malgré la divergence des labels.
Tâche 4 : Forcer le remplacement avec replace_triggered_by
Utilisez replace_triggered_by pour forcer le remplacement d'un conteneur quand une ressource null_resource change de valeur.
Indice :
replace_triggered_by = [null_resource.trigger.id]
Vérification : Modifier le trigger → terraform plan propose de remplacer le conteneur.
Tâche 5 : Tester l'erreur prevent_destroy en détail
Modifiez la configuration pour forcer un remplacement (-/+) d'une ressource avec prevent_destroy = true.
Indice : Changer le
named'un conteneur force sa recréation. Siprevent_destroy = true, Terraform bloque avant même de tenter la destruction.
Vérification : terraform apply retourne une erreur claire indiquant que la destruction est bloquée.
🗂️ Mini-Projet : Configuration production-ready complète
# main.tf
resource "docker_container" "database" {
name = "prod-database"
image = docker_image.postgres.image_id
ports {
internal = 5432
external = 5432
}
lifecycle {
# Ne JAMAIS détruire la base de données accidentellement
prevent_destroy = true
# Ignorer les changements de variables d'environnement (gérées par un vault)
ignore_changes = [env]
}
}
resource "docker_container" "web" {
name = "prod-web-${var.image_tag}"
image = docker_image.nginx.image_id
ports {
internal = 80
external = 80
}
lifecycle {
# Créer le nouveau conteneur avant de supprimer l'ancien
create_before_destroy = true
}
}Checkpoints :
terraform destroyavecprevent_destroy = true→ erreurInstance cannot be destroyed- Changer
namesur un conteneur aveccreate_before_destroy = true→+/-dans le plan ignore_changes = [labels]→ modification manuelle de labels ignorée parterraform planreplace_triggered_bysur une valeur changeante → le conteneur est remplacélifecycle { prevent_destroy = true }bloque même lesterraform destroy -target