Terraform 27: Refactorizar con seguridad usando state mv, import y moved
easy⏱ 5 mincourseterraform
Bloques moved: renombrar in-place, versionado
Un bloque moved le dice a Terraform "el recurso que antes estaba en la dirección A ahora está en B — actualizá el state, no recrees." Vive en tu .tf, así que el renombrado se revisa en PR y se aplica como cualquier otro cambio. Preferilo sobre el CLI imperativo porque es declarativo y reproducible para todos los que corran apply.
# You renamed the resource from "old" to "main" in config.
resource "azurerm_storage_account" "main" {
name = "myorgordersdev"
resource_group_name = "myorg-orders-dev-rg"
location = "westus2"
account_tier = "Standard"
account_replication_type = "LRS"
}
# This block updates state instead of destroy+create.
moved {
from = azurerm_storage_account.old
to = azurerm_storage_account.main
}
Bloques import: adoptar recursos existentes
Cuando un recurso ya existe en Azure pero no en el state (creado a mano o por otra herramienta), un bloque import (Terraform 1.5+) lo pone bajo gestión. Le das la dirección destino y el id de la nube; terraform plan muestra qué se va a importar y apply lo registra en el state — sin destruir, sin recrear. Es el sucesor declarativo del viejo comando terraform import.
# Adopt a resource group that already exists in Azure.
import {
to = azurerm_resource_group.orders
id = "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/myorg-orders-dev-rg"
}
resource "azurerm_resource_group" "orders" {
name = "myorg-orders-dev-rg"
location = "westus2"
}
terraform state mv es la salida imperativa
Antes de que existieran los bloques moved, renombrabas con el CLI: terraform state mv <viejo> <nuevo>. Sigue siendo útil para cirugía puntual (por ejemplo mover un recurso a un módulo: terraform state mv azurerm_storage_account.main module.storage.azurerm_storage_account.main). Pero muta el state al instante sin rastro en PR — usá primero los bloques moved, y siempre corré terraform plan después para confirmar cero destrucciones.
Emití un bloque moved
Implementá movedBlock(from, to) para que devuelva el texto HCL de un bloque moved. Para movedBlock("azurerm_storage_account.old", "azurerm_storage_account.main") la salida debe contener moved {, una línea from = con la dirección vieja, y una línea to con la dirección nueva. El starter loguea la llamada.