Aller au contenu
Infrastructure as Code medium
🔐 Alerte sécurité — Incident supply chain Trivy : lire mon analyse de l'attaque

terraform state mv — déplacer ou renommer une ressource

9 min de lecture

logo terraform

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.

  • 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 moved comme alternative déclarative (Terraform >= 1.1)
  • Éviter les erreurs courantes de désynchronisation code/state
Fenêtre de terminal
terraform state mv [options] SOURCE DESTINATION
ParamètreRôle
SOURCEAdresse actuelle de la ressource dans le state
DESTINATIONNouvelle adresse souhaitée
-dry-runSimule 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.

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.

  1. Vérifier l’état initial

    Identifiez la ressource à renommer avec state list :

    Fenêtre de terminal
    terraform state list
    libvirt_network.net
    libvirt_volume.db
    libvirt_volume.web
  2. Simuler le déplacement

    Utilisez -dry-run pour vérifier avant de modifier :

    Fenêtre de terminal
    terraform state mv -dry-run libvirt_volume.web libvirt_volume.frontend
    Would move "libvirt_volume.web" to "libvirt_volume.frontend"

    Aucune modification n’est faite — Terraform affiche ce qu’il ferait.

  3. Exécuter le déplacement

    Fenêtre de terminal
    terraform state mv libvirt_volume.web libvirt_volume.frontend
    Move "libvirt_volume.web" to "libvirt_volume.frontend"
    Successfully moved 1 object(s).
  4. Confirmer la nouvelle adresse

    Fenêtre de terminal
    terraform state list
    libvirt_network.net
    libvirt_volume.db
    libvirt_volume.frontend

    L’infrastructure n’a pas été touchée — seule la référence dans le state a changé.

  5. Mettre à jour le code HCL

    Renommez le bloc dans votre fichier .tf pour correspondre au state :

    # Avant
    resource "libvirt_volume" "web" { ... }
    # Après
    resource "libvirt_volume" "frontend" { ... }
  6. Vérifier la synchronisation

    Fenêtre de terminal
    terraform plan
    No changes. Your infrastructure matches the configuration.

    No changes confirme que le state et le code sont synchronisés. L’infrastructure est intacte.

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

Fenêtre de terminal
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 :

Fenêtre de terminal
terraform state list
libvirt_network.net
libvirt_volume.frontend
module.db_storage.libvirt_volume.disk

Un terraform plan après mise à jour du code confirme : No changes.

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.

Critèreterraform state mvBloc moved
Version minimaleToutesTerraform >= 1.1
ModeImpératif (commande CLI)Déclaratif (dans le code)
TraçabilitéAucune trace dans le codeVisible dans l’historique Git
CollaborationChaque membre doit exécuter la commandeAutomatique pour toute l’équipe
Risque d’oubliÉlevé (code à mettre à jour manuellement)Faible (code et déplacement couplés)
Backends distantsFonctionne partoutFonctionne partout

Si l’adresse source n’existe pas dans le state, Terraform refuse le déplacement :

Fenêtre de terminal
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.

SymptômeCause probableSolution
Invalid source addressL’adresse source n’existe pas dans le stateVérifier avec terraform state list
Plan affiche destroy + create après mvLe code HCL n’a pas été mis à jourRenommer le bloc dans le .tf pour correspondre
Cannot move to address already in stateLa destination existe déjàChoisir un autre nom ou retirer l’existant d’abord
No state file was foundAucun apply effectuéLancer terraform apply d’abord
Le moved block ne fonctionne pasVersion Terraform < 1.1Mettre à jour ou utiliser state mv
  • terraform state mv renomme ou déplace une ressource dans le state sans toucher à l’infrastructure
  • Utilisez -dry-run pour 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 plan qui affiche No changes confirme que le renommage est réussi

Ce site vous est utile ?

Sachez que moins de 1% des lecteurs soutiennent ce site.

Je maintiens +700 guides gratuits, sans pub ni tracing. Aujourd'hui, ce site ne couvre même pas mes frais d'hébergement, d'électricité, de matériel, de logiciels, mais surtout de cafés.

Un soutien régulier, même symbolique, m'aide à garder ces ressources gratuites et à continuer de produire des guides de qualité. Merci pour votre appui.

Abonnez-vous et suivez mon actualité DevSecOps sur LinkedIn