
terraform state mv renomme ou déplace une ressource dans le state sans détruire l’infrastructure réelle. Quand vous refactorisez votre code Terraform — renommer un bloc, extraire une ressource dans un module — cette commande évite un cycle destroy + recreate coûteux et risqué. Depuis Terraform 1.1, le bloc moved offre une alternative déclarative encore plus sûre.
Prérequis : savoir utiliser terraform state list pour trouver l’adresse d’une ressource et terraform state show pour inspecter ses attributs.
Ce que vous allez apprendre
Section intitulée « Ce que vous allez apprendre »- Renommer une ressource avec
terraform state mv - Vérifier le résultat avec une simulation
dry-run - Déplacer une ressource vers un module
- Utiliser le bloc
movedcomme alternative déclarative (Terraform >= 1.1) - Éviter les erreurs courantes de désynchronisation code/state
terraform state mv [options] SOURCE DESTINATION| Paramètre | Rôle |
|---|---|
SOURCE | Adresse actuelle de la ressource dans le state |
DESTINATION | Nouvelle adresse souhaitée |
-dry-run | Simule le déplacement sans modifier le state |
L’adresse suit le format type.nom pour une ressource racine ou module.nom_module.type.nom pour une ressource dans un module.
Renommer une ressource
Section intitulée « Renommer une ressource »Le cas le plus fréquent : vous améliorez la lisibilité de votre code en renommant un bloc. Sans state mv, Terraform détruirait l’ancienne ressource et en créerait une nouvelle.
-
Vérifier l’état initial
Identifiez la ressource à renommer avec
state list:Fenêtre de terminal terraform state listlibvirt_network.netlibvirt_volume.dblibvirt_volume.web -
Simuler le déplacement
Utilisez
-dry-runpour vérifier avant de modifier :Fenêtre de terminal terraform state mv -dry-run libvirt_volume.web libvirt_volume.frontendWould move "libvirt_volume.web" to "libvirt_volume.frontend"Aucune modification n’est faite — Terraform affiche ce qu’il ferait.
-
Exécuter le déplacement
Fenêtre de terminal terraform state mv libvirt_volume.web libvirt_volume.frontendMove "libvirt_volume.web" to "libvirt_volume.frontend"Successfully moved 1 object(s). -
Confirmer la nouvelle adresse
Fenêtre de terminal terraform state listlibvirt_network.netlibvirt_volume.dblibvirt_volume.frontendL’infrastructure n’a pas été touchée — seule la référence dans le state a changé.
-
Mettre à jour le code HCL
Renommez le bloc dans votre fichier
.tfpour correspondre au state :# Avantresource "libvirt_volume" "web" { ... }# Aprèsresource "libvirt_volume" "frontend" { ... } -
Vérifier la synchronisation
Fenêtre de terminal terraform planNo changes. Your infrastructure matches the configuration.No changesconfirme que le state et le code sont synchronisés. L’infrastructure est intacte.
Déplacer vers un module
Section intitulée « Déplacer vers un module »Quand vous refactorisez votre code pour extraire une ressource dans un module, state mv évite la recréation. La destination utilise le préfixe module.<nom_module>. :
terraform state mv 'libvirt_volume.db' 'module.db_storage.libvirt_volume.disk'Move "libvirt_volume.db" to "module.db_storage.libvirt_volume.disk"Successfully moved 1 object(s).La vérification confirme le résultat :
terraform state listlibvirt_network.netlibvirt_volume.frontendmodule.db_storage.libvirt_volume.diskUn terraform plan après mise à jour du code confirme : No changes.
Alternative déclarative : le bloc moved
Section intitulée « Alternative déclarative : le bloc moved »Depuis Terraform 1.1, le bloc moved permet de déclarer un renommage directement dans le code HCL. Terraform gère le déplacement automatiquement au prochain apply — sans commande manuelle.
resource "libvirt_volume" "web_disk" { name = "web-server.qcow2" pool = "default" capacity = 4294967296 # ...}
moved { from = libvirt_volume.frontend to = libvirt_volume.web_disk}Le terraform plan affiche clairement le déplacement prévu :
# libvirt_volume.frontend has moved to libvirt_volume.web_disk resource "libvirt_volume" "web_disk" { id = "/var/lib/libvirt/images/web-server.qcow2" name = "web-server.qcow2" # (8 unchanged attributes hidden) }
Plan: 0 to add, 0 to change, 0 to destroy.Un terraform apply finalise le déplacement — 0 destruction, 0 création :
Apply complete! Resources: 0 added, 0 changed, 0 destroyed.Le bloc moved fonctionne aussi pour accompagner un refactoring vers un module :
moved { from = libvirt_volume.db to = module.db_storage.libvirt_volume.disk}Cette approche est souvent plus sûre qu’une commande manuelle quand le déplacement fait partie d’une refonte versionnée dans Git.
state mv ou moved : lequel choisir ?
Section intitulée « state mv ou moved : lequel choisir ? »| Critère | terraform state mv | Bloc moved |
|---|---|---|
| Version minimale | Toutes | Terraform >= 1.1 |
| Mode | Impératif (commande CLI) | Déclaratif (dans le code) |
| Traçabilité | Aucune trace dans le code | Visible dans l’historique Git |
| Collaboration | Chaque membre doit exécuter la commande | Automatique pour toute l’équipe |
| Risque d’oubli | Élevé (code à mettre à jour manuellement) | Faible (code et déplacement couplés) |
| Backends distants | Fonctionne partout | Fonctionne partout |
Erreur : adresse source invalide
Section intitulée « Erreur : adresse source invalide »Si l’adresse source n’existe pas dans le state, Terraform refuse le déplacement :
terraform state mv libvirt_volume.inexistant libvirt_volume.autre╷│ Error: Invalid source address││ Cannot move libvirt_volume.inexistant: does not match anything in the current│ state.╵Vérifiez toujours l’adresse exacte avec terraform state list avant un state mv.
Dépannage
Section intitulée « Dépannage »| Symptôme | Cause probable | Solution |
|---|---|---|
Invalid source address | L’adresse source n’existe pas dans le state | Vérifier avec terraform state list |
Plan affiche destroy + create après mv | Le code HCL n’a pas été mis à jour | Renommer le bloc dans le .tf pour correspondre |
Cannot move to address already in state | La destination existe déjà | Choisir un autre nom ou retirer l’existant d’abord |
No state file was found | Aucun apply effectué | Lancer terraform apply d’abord |
Le moved block ne fonctionne pas | Version Terraform < 1.1 | Mettre à jour ou utiliser state mv |
À retenir
Section intitulée « À retenir »terraform state mvrenomme ou déplace une ressource dans le state sans toucher à l’infrastructure- Utilisez
-dry-runpour simuler avant de modifier le state - Pensez toujours à mettre à jour le code HCL après un
state mv— sinon le prochain plan détruira et recréera la ressource - Le déplacement vers un module utilise le préfixe
module.<nom>.dans l’adresse destination - Le bloc
moved(Terraform >= 1.1) est l’alternative déclarative recommandée en équipe — traçable et automatique - Un
terraform planqui afficheNo changesconfirme que le renommage est réussi