Terraform Associate

Deep Dive

Practicar ahora
D6 · Estado de Terraform

Comandos de state, import y workspaces

Los comandos de state permiten inspeccionar y manipular el estado sin destruir infraestructura. El import incorpora recursos existentes al estado. Los workspaces permiten múltiples entornos con la misma configuración.

terraform state list y show

# Listar todos los recursos en el estado
terraform state list

# Salida ejemplo:
# aws_vpc.main
# aws_subnet.public[0]
# aws_subnet.public[1]
# aws_subnet.private["us-east-1a"]
# module.eks.aws_eks_cluster.this
# data.aws_ami.ubuntu

# Filtrar por prefijo
terraform state list module.eks
# module.eks.aws_eks_cluster.this
# module.eks.aws_iam_role.cluster

# Ver los atributos detallados de un recurso específico
terraform state show aws_vpc.main
terraform state show 'aws_subnet.private["us-east-1a"]'  # comillas necesarias para for_each

# Ver en formato JSON (todos los recursos)
terraform show -json | jq '.values.root_module.resources[]'

💡 Comillas en direcciones con for_each

Las direcciones de recursos creados con for_each incluyen la clave entre corchetes y comillas: aws_subnet.private["us-east-1a"]. En la shell debes escapar las comillas o envolver la dirección en comillas simples.

terraform state mv y rm

terraform state mv — mover/renombrar

# Renombrar un recurso en el estado
# (útil cuando cambias el nombre local en el código sin recrear)
terraform state mv   aws_instance.old_name   aws_instance.new_name

# Mover recurso a dentro de un módulo
terraform state mv   aws_vpc.main   module.networking.aws_vpc.main

# Mover recurso desde un módulo al root
terraform state mv   module.old.aws_s3_bucket.data   aws_s3_bucket.data

# ⚠️ Después de mv, actualiza también el código .tf
# para que coincida con la nueva dirección

terraform state rm — eliminar del estado

# Eliminar un recurso del estado SIN destruirlo en la nube
# Útil cuando ya no quieres que Terraform lo gestione
terraform state rm aws_instance.legacy

# Eliminar todos los recursos de un módulo del estado
terraform state rm module.old_module

# ⚠️ El recurso sigue existiendo en la nube
# Solo deja de estar rastreado por Terraform
# Si luego ejecutas apply, Terraform IGNORARÁ ese recurso
# (no lo destruirá porque no está en el estado)
ComandoEfecto en estadoEfecto en infra real
terraform state mvCambia la dirección del recurso en tfstateNinguno — el recurso real no se toca
terraform state rmElimina el recurso del tfstateNinguno — el recurso real sigue existiendo
terraform destroyElimina el recurso del tfstate🔥 DESTRUYE el recurso en la nube
terraform apply (add)Añade el recurso al tfstateCrea el recurso en la nube

terraform state pull y push

# Descargar el estado remoto a stdout (útil para inspección o backup)
terraform state pull > backup-state.json

# Ver el estado remoto sin guardarlo
terraform state pull | jq '.resources[].type' | sort | uniq

# Subir un estado local al backend remoto
# ⚠️ PELIGROSO: sobrescribe el estado remoto
terraform state push backup-state.json

# terraform state push requiere que el serial del estado a subir
# sea mayor al serial actual, a menos que uses -force (muy peligroso)

⚠️ terraform state push puede corromper el estado

terraform state push sobrescribe el estado remoto. Úsalo solo en situaciones de recuperación de desastres, nunca como flujo de trabajo normal. Si el estado subido está desactualizado, puede causar que Terraform recree o destruya recursos incorrectamente.

terraform import e import block

El import permite incorporar recursos existentes en la nube (creados manualmente o con otras herramientas) al estado de Terraform para que pueda gestionarlos.

Pasos para importar con terraform import (CLI clásico)

# Paso 1: Define el bloque resource en tu código .tf
# (con los argumentos que ya tiene el recurso)
resource "aws_instance" "legacy" {
  # Debes definir el recurso antes de importar
  ami           = "ami-0c55b159cbfafe1f0"  # obtén estos valores de la consola
  instance_type = "t3.micro"
}

# Paso 2: Importa el recurso usando su ID real en la nube
terraform import aws_instance.legacy i-0123456789abcdef0

# Paso 3: Ejecuta terraform plan para ver las diferencias
terraform plan
# Puede mostrar ~ cambios si el bloque resource no coincide exactamente

# Paso 4: Ajusta el código .tf hasta que terraform plan muestre "No changes"

import block (Terraform 1.5+ — forma moderna)

# Import block en el código HCL — más declarativo y reutilizable
import {
  to = aws_instance.legacy          # dirección en Terraform
  id = "i-0123456789abcdef0"       # ID real en la nube
}

resource "aws_instance" "legacy" {
  ami           = "ami-0c55b159cbfafe1f0"
  instance_type = "t3.micro"
}

# Ejecutar:
terraform plan   # muestra el plan de importación
terraform apply  # realiza la importación

# Bonus: terraform 1.5+ puede GENERAR el bloque resource automáticamente:
terraform plan -generate-config-out=generated.tf

💡 ¿Cómo sé el ID de importación?

Cada tipo de recurso tiene su propio formato de ID de importación. La documentación del provider en el registry especifica el formato para cada recurso en la sección "Import". Por ejemplo: aws_instance usa el Instance ID (i-xxx), aws_s3_bucket usa el nombre del bucket.

Workspaces CLI

Los workspaces CLI permiten mantener múltiples estados independientes con la misma configuración. Cada workspace tiene su propio tfstate.

# Comandos de workspace
terraform workspace list       # listar todos los workspaces
terraform workspace show       # mostrar el workspace activo
terraform workspace new dev    # crear workspace "dev" y activarlo
terraform workspace select prod  # cambiar al workspace "prod"
terraform workspace delete dev   # eliminar workspace "dev" (no puede estar activo)

# terraform.workspace — variable especial con el nombre del workspace activo
resource "aws_instance" "web" {
  instance_type = terraform.workspace == "prod" ? "t3.large" : "t3.micro"

  tags = {
    Environment = terraform.workspace
  }
}

# Almacenamiento del estado por workspace:
# Backend local:    terraform.tfstate.d/<workspace>/terraform.tfstate
# Backend S3:       <bucket>/<key>.tfstate.d/<workspace>/terraform.tfstate
# Backend HCP:      workspace separado en la organización
CaracterísticaWorkspaces CLIWorkspaces HCP Terraform
¿Qué son?Múltiples estados del mismo directorio de trabajoEntornos de ejecución completos con config, variables, runs, historial
Estado separado✅ Sí✅ Sí
Variables separadas❌ No — comparten variables del código✅ Sí — cada workspace tiene sus propias variables
Acceso granular❌ No✅ Sí — permisos por workspace
Historial de runs❌ No✅ Sí
Recomendado paraEntornos simples, pruebas rápidasEntornos de producción, colaboración en equipo

¿Entendiste este tema?

Pon a prueba lo que acabas de aprender

Un ingeniero ejecuta terraform state rm aws_s3_bucket.legacy para dejar de gestionar un bucket con Terraform. ¿Qué ocurrirá con el bucket de S3 en AWS después de este comando?