Terraform Associate
Deep Dive
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.
Contenido
# 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 — 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)
| Comando | Efecto en estado | Efecto en infra real |
|---|---|---|
| terraform state mv | Cambia la dirección del recurso en tfstate | Ninguno — el recurso real no se toca |
| terraform state rm | Elimina el recurso del tfstate | Ninguno — el recurso real sigue existiendo |
| terraform destroy | Elimina el recurso del tfstate | 🔥 DESTRUYE el recurso en la nube |
| terraform apply (add) | Añade el recurso al tfstate | Crea el recurso en la nube |
# 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.
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.
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ística | Workspaces CLI | Workspaces HCP Terraform |
|---|---|---|
| ¿Qué son? | Múltiples estados del mismo directorio de trabajo | Entornos 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 para | Entornos simples, pruebas rápidas | Entornos 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?