Terraform Associate

Deep Dive

Practicar ahora
D7 · Implementación y mantenimiento

CLI avanzado: import, logging y debugging

Para el examen y el trabajo diario, es fundamental saber cómo importar infraestructura existente, depurar problemas con los niveles de log, liberar locks bloqueados y usar herramientas como terraform console para inspeccionar expresiones.

terraform import en profundidad

El proceso completo de importación tiene pasos específicos que debes conocer para el examen.

1

Identificar el recurso en la nube

Obtén el ID del recurso desde la consola cloud o CLI. Cada tipo de recurso tiene su propio formato de ID (consulta la documentación del provider).

2

Definir el bloque resource en HCL

DEBES crear el bloque resource en tu .tf ANTES de ejecutar terraform import. Si no existe el bloque, el import fallará.

3

Ejecutar terraform import

Comando: terraform import <dirección> <id-real>. Terraform consulta la API cloud, obtiene el estado actual y lo escribe en el tfstate.

4

Ejecutar terraform plan

Compara lo que dice el tfstate (estado real) con tu bloque resource (configuración deseada). Casi siempre habrá diferencias.

5

Ajustar el código HCL

Modifica el bloque resource para que coincida con la configuración real del recurso importado. Repite plan hasta ver "No changes".

6

Verificar y commitar

Con "No changes" en el plan, el recurso está correctamente importado y gestionado por Terraform.

# Ejemplo completo: importar una VPC existente

# Paso 1: Obtener el ID de la VPC desde AWS
# aws ec2 describe-vpcs --query 'Vpcs[?Tags[?Key==`Name`&&Value==`legacy-vpc`]].VpcId'
# Output: "vpc-0abc123def456"

# Paso 2: Crear el bloque resource (mínimo requerido)
# main.tf:
resource "aws_vpc" "legacy" {
  cidr_block = "172.16.0.0/16"  # valor real — obtén de la consola
}

# Paso 3: Importar
terraform import aws_vpc.legacy vpc-0abc123def456

# Paso 4: Ver el plan
terraform plan
# ~ aws_vpc.legacy  (modificar porque faltan atributos)

# Paso 5: Actualizar el código con todos los atributos
resource "aws_vpc" "legacy" {
  cidr_block           = "172.16.0.0/16"
  enable_dns_support   = true     # ajustar según plan
  enable_dns_hostnames = true
  tags = {
    Name = "legacy-vpc"
  }
}

# Repetir plan hasta ver: "No changes. Your infrastructure matches the configuration."

# ALTERNATIVA: import block + generate-config (Terraform 1.5+)
import {
  to = aws_vpc.legacy
  id = "vpc-0abc123def456"
}

terraform plan -generate-config-out=vpc_legacy.tf  # genera el bloque resource automáticamente

💡 Formatos de ID por tipo de recurso AWS

RecursoFormato de ID
aws_instancei-0123456789abcdef0
aws_vpcvpc-0abc123def456
aws_s3_bucketnombre-del-bucket
aws_iam_rolenombre-del-role
aws_security_groupsg-0abc123def456
aws_db_instanceidentificador-de-la-db

terraform apply -replace (reemplaza terraform taint)

⚠️ terraform taint está deprecado desde v0.15.2

terraform taint marcaba un recurso para ser recreado en el siguiente apply, pero sin mostrar el plan primero. Fue reemplazado por terraform apply -replace=<dirección>, que es más seguro porque muestra explícitamente qué va a cambiar antes de actuar.

Antes (deprecado)

# terraform taint — NO usar
terraform taint aws_instance.web
# Marca el recurso pero no muestra el plan
# El próximo apply lo destruye y recrea
# sin que puedas revisar el cambio antes

Ahora (moderno)

# terraform apply -replace — usar esto
terraform plan -replace=aws_instance.web
# Muestra el plan de reemplazo primero

terraform apply -replace=aws_instance.web
# Fuerza recreación de ese recurso concreto

# Múltiples recursos:
terraform apply   -replace=aws_instance.web   -replace=aws_eip.web

🎯 Para el examen

  • terraform taint está deprecado desde v0.15.2 — el examen puede mencionar ambos pero la respuesta correcta usa -replace
  • -replace muestra el plan antes de actuar (símbolo -/+ en el output del plan)
  • • Útil para forzar la recreación de un recurso que está en mal estado sin destruir toda la infraestructura
  • • La dirección sigue el formato tipo.nombre o module.nombre.tipo.nombre para módulos

TF_LOG: niveles de logging

Terraform usa variables de entorno para controlar el nivel de logging. Son imprescindibles para depurar problemas con providers o el core.

NivelVerbosidadCuándo usar
TRACEMáxima — todoDepuración profunda. Muestra cada llamada a API, requests HTTP completos. Muy verboso.
DEBUGAltaDepuración detallada. Muestra decisiones internas del core y providers.
INFOMediaInformación general del flujo de ejecución. Recomendado para entender qué pasa.
WARNBaja — advertenciasSolo advertencias. Situaciones no críticas pero que requieren atención.
ERRORMínima — solo erroresSolo errores críticos que causan fallos.
OFFNinguna (default)Sin logging adicional (comportamiento por defecto).
# Habilitar logging en la sesión actual
export TF_LOG=DEBUG
terraform plan

# Guardar logs en un archivo (sin esto, van a stderr)
export TF_LOG=TRACE
export TF_LOG_PATH=/tmp/terraform-debug.log
terraform apply

# Separar logs del Core y del Provider (Terraform 0.15+)
export TF_LOG_CORE=INFO       # logs del núcleo de Terraform
export TF_LOG_PROVIDER=DEBUG  # logs del provider (llamadas a AWS API, etc.)

# Desactivar logging
unset TF_LOG
# O:
export TF_LOG=OFF

# Windows PowerShell:
$env:TF_LOG = "DEBUG"
$env:TF_LOG_PATH = "C:\temp\tf-debug.log"
terraform plan

🎯 Para el examen

El orden de verbosidad de menor a mayor es: ERROR → WARN → INFO → DEBUG → TRACE. TF_LOG_PATH guarda los logs en un archivo (sin esto solo van a stderr). TF_LOG_CORE y TF_LOG_PROVIDER permiten controlar el logging por separado.

terraform force-unlock

Cuando un terraform apply se interrumpe abruptamente (kill, pérdida de conexión, crash), puede dejar el lock del estado sin liberar. terraform force-unlock libera manualmente ese lock.

# Error típico cuando el estado está bloqueado:
# Error acquiring the state lock: ConditionalCheckFailedException: ...
# Lock Info:
#   ID:        3a1c2fa8-b5d9-4f71-a3c7-123456789abc  ← este es el Lock ID
#   Path:      terraform.tfstate
#   Operation: OperationTypeApply
#   Who:       user@hostname
#   Version:   1.6.3
#   Created:   2024-01-15 10:23:45 UTC
#   Info:

# Liberar el lock con el ID mostrado en el error
terraform force-unlock 3a1c2fa8-b5d9-4f71-a3c7-123456789abc

# Confirmar con -force (omite la confirmación interactiva)
terraform force-unlock -force 3a1c2fa8-b5d9-4f71-a3c7-123456789abc

⚠️ Verifica que no hay apply en curso antes de force-unlock

Si liberas un lock mientras hay otro proceso de Terraform ejecutándose (que tú no ves), puedes causar que dos applies corran simultáneamente y corrompan el estado. Antes de ejecutar force-unlock, verifica que el proceso que puso el lock realmente ha terminado.

terraform providers y console

terraform providers

Lista todos los providers requeridos por la configuración actual y sus versiones instaladas.

terraform providers
# Providers required by configuration:
# .
# ├── provider[registry.terraform.io/hashicorp/aws] ~> 5.0
# └── module.vpc
#     └── provider[registry.terraform.io/hashicorp/aws] >= 4.0

# Actualizar lock file para múltiples plataformas:
terraform providers lock   -platform=linux_amd64   -platform=darwin_arm64

terraform console

REPL interactivo para evaluar expresiones HCL. Tiene acceso al estado y a las variables.

terraform console
> var.environment
"prod"
> max(3, 7, 2)
7
> join("-", ["api", "prod", "v1"])
"api-prod-v1"
> jsonencode({env = "prod"})
"{"env":"prod"}"
> cidrsubnet("10.0.0.0/16", 8, 1)
"10.0.1.0/24"
> Ctrl+C o Ctrl+D para salir

Paralelismo y rendimiento

Terraform ejecuta operaciones en paralelo cuando los recursos no tienen dependencias entre sí. El flag -parallelism controla cuántas operaciones concurrentes permite.

# Valor por defecto: 10 operaciones concurrentes
terraform apply

# Aumentar el paralelismo (más rápido pero más carga en la API)
terraform apply -parallelism=20

# Reducir el paralelismo (útil si la API de la nube tiene rate limiting)
terraform apply -parallelism=5

# El mismo flag funciona con plan y destroy
terraform plan -parallelism=15
terraform destroy -parallelism=5

# ⚠️ Aumentar mucho puede causar errores de throttling en las APIs cloud
# AWS, Azure y GCP tienen límites de rate en sus APIs
Variable de entornoPropósitoEjemplo
TF_LOGNivel de logging globalTF_LOG=DEBUG
TF_LOG_PATHArchivo donde guardar los logsTF_LOG_PATH=/tmp/tf.log
TF_LOG_CORENivel de logging solo del coreTF_LOG_CORE=INFO
TF_LOG_PROVIDERNivel de logging solo del providerTF_LOG_PROVIDER=TRACE
TF_VAR_nombreValor de una variable de entradaTF_VAR_env=prod
TF_CLI_ARGSFlags adicionales para todos los comandosTF_CLI_ARGS="-no-color"
TF_CLI_ARGS_planFlags adicionales solo para terraform planTF_CLI_ARGS_plan="-refresh=false"
TF_DATA_DIRDirectorio alternativo para .terraform/TF_DATA_DIR=/tmp/tf-plugins

¿Entendiste este tema?

Pon a prueba lo que acabas de aprender

Un ingeniero ejecuta terraform apply y el proceso se interrumpe por un problema de red. Al intentar ejecutar terraform plan de nuevo, recibe: 'Error acquiring the state lock'. ¿Qué debe hacer?