Terraform Actions es una innovación revolucionaria introducida en Terraform 1.14 que permite gestionar operaciones del día 2 directamente desde tu código de infraestructura. Esta herramienta unifica el aprovisionamiento y la administración continua de recursos cloud sin necesidad de scripts externos o cambios manuales en la consola.
Qué son Terraform Actions y por qué son importantes
Las operaciones tradicionales de Terraform se limitaban a crear, actualizar y destruir recursos (CRUD). Sin embargo, el mantenimiento real de infraestructura requiere acciones adicionales: ejecutar funciones Lambda, invalidar cachés de CloudFront, enviar notificaciones SNS o ejecutar playbooks de Ansible. Antes de esta feature, los equipos DevOps debían salir del flujo de trabajo de IaC para realizar estas tareas manualmente.
Ahora puedes codificar estas operaciones directamente en tus archivos .tf y ejecutarlas mediante triggers automáticos o comandos CLI. Esto representa el primer paso hacia la unificación de Terraform y Ansible en un único workflow de infraestructura.
Sintaxis básica de Terraform Actions
La declaración de una acción sigue una estructura simple y familiar para cualquier usuario de HashiCorp Configuration Language:
action "aws_lambda_invoke" "notificacion" {
config {
function_name = aws_lambda_function.mi_funcion.function_name
payload = jsonencode({
mensaje = "Infraestructura desplegada correctamente"
timestamp = timestamp()
})
}
}
Cada bloque action requiere dos identificadores: el tipo de acción (prefijado por el proveedor) y un nombre simbólico único. El bloque config contiene los argumentos específicos que acepta esa acción según la documentación del provider en Terraform Registry.
Dos formas de ejecutar acciones en tu infraestructura
Invocación manual mediante CLI
Puedes ejecutar cualquier acción bajo demanda utilizando el flag -invoke en tus comandos habituales:
terraform plan -invoke=action.aws_lambda_invoke.notificacion
terraform apply -invoke=action.aws_lambda_invoke.notificacion
Este método es ideal para operaciones puntuales de mantenimiento, testing o troubleshooting que no necesitas automatizar completamente.
Triggers automáticos del ciclo de vida
La verdadera potencia aparece cuando vinculas acciones a eventos del lifecycle de recursos. Puedes configurar triggers que se ejecuten automáticamente en momentos específicos:
resource "aws_instance" "servidor_web" {
ami = "ami-0c55b159cbfafe1f0"
instance_type = "t3.micro"
lifecycle {
action_trigger {
events = [after_create, after_update]
actions = [action.aws_lambda_invoke.notificacion]
}
}
}
Los eventos disponibles son before_create, after_create, before_update y after_update, permitiendo orquestar flujos complejos de automatización.
Casos de uso prácticos para Day 2 Operations
Invalidación automática de caché CDN
Uno de los escenarios más comunes es limpiar cachés de CloudFront después de actualizar contenido en S3:
resource "aws_s3_object" "contenido_estatico" {
bucket = aws_s3_bucket.sitio.id
key = "index.html"
source = "dist/index.html"
etag = filemd5("dist/index.html")
lifecycle {
action_trigger {
events = [after_update]
actions = [action.aws_cloudfront_create_invalidation.limpiar_cache]
}
}
}
action "aws_cloudfront_create_invalidation" "limpiar_cache" {
config {
distribution_id = aws_cloudfront_distribution.cdn.id
paths = ["/*"]
}
}
Esta configuración garantiza que los usuarios siempre vean la versión más reciente de tu aplicación sin intervención manual. Puedes revisar más ejemplos de automatización DevOps en nuestra categoría dedicada a workflows de despliegue continuo.
Integración con Ansible para configuración post-despliegue
El provider de Ansible permite ejecutar playbooks directamente desde el código IaC, cerrando la brecha entre aprovisionamiento y configuración:
action "ansible_playbook_run" "configurar_servidor" {
config {
playbook_path = "${path.module}/playbooks/setup.yml"
inventory = ansible_inventory.dinamico.id
extra_vars = {
app_version = var.version_aplicacion
ambiente = var.entorno
}
}
}
resource "aws_instance" "app_server" {
# ... configuración de instancia
lifecycle {
action_trigger {
events = [after_create]
actions = [action.ansible_playbook_run.configurar_servidor]
}
}
}
Esta integración es especialmente valiosa para equipos que ya tienen inversión en playbooks de Ansible y buscan consolidar su stack de automatización. La documentación oficial de HashiCorp ofrece guías completas sobre esta integración.
Gestión de estado de instancias EC2
Detener instancias fuera de horario laboral para optimizar costos es otra aplicación directa:
action "aws_ec2_stop_instance" "apagar_dev" {
config {
instance_id = aws_instance.entorno_dev.id
}
}
# Ejecutar manualmente cada viernes:
# terraform apply -invoke=action.aws_ec2_stop_instance.apagar_dev
También puedes combinar esto con programadores externos o sistemas de monitoreo como Uptime Kuma para crear políticas de apagado inteligente basadas en métricas reales de uso.
Meta-argumentos soportados en acciones
Las acciones heredan los meta-argumentos estándar que ya conoces de recursos normales, permitiendo patrones avanzados de uso:
- count: Crear múltiples instancias de la misma acción con diferentes configuraciones
- for_each: Iterar sobre mapas o conjuntos para generar acciones dinámicamente
- provider: Especificar configuraciones alternativas del proveedor
- depends_on: Definir dependencias explícitas entre acciones
action "aws_lambda_invoke" "notificar_regiones" {
for_each = toset(var.regiones_activas)
provider = aws.[each.key]
config {
function_name = "notificador-${each.key}"
payload = jsonencode({
region = each.key
evento = "deployment_completed"
})
}
}
Ejecución condicional con el argumento condition
Puedes controlar cuándo se ejecuta una acción mediante expresiones booleanas evaluadas en tiempo de planificación:
action "aws_sns_publish" "alerta_produccion" {
condition = var.entorno == "produccion" && var.habilitar_alertas
config {
topic_arn = aws_sns_topic.alertas.arn
message = "Despliegue completado en producción"
}
}
Esto evita tener que crear configuraciones separadas o usar lógica compleja de módulos para manejar diferentes ambientes. Similar a cómo gestionarías secretos con Vaultwarden, puedes tener configuraciones específicas por entorno manteniendo un código base unificado.
Limitaciones importantes a considerar
Aunque el concepto es poderoso, existen restricciones técnicas que debes conocer:
- Sin estado persistente: Los resultados de acciones no se almacenan en el state file, por lo que no puedes referenciar sus outputs en otros recursos
- No bloquean el plan: Las acciones se ejecutan de forma asíncrona y no afectan las decisiones de planificación
- Dependencia del provider: No todos los providers implementan acciones aún; verifica la disponibilidad en Terraform Registry
- Sin rollback automático: Si una acción falla después de aplicar cambios, debes manejar la recuperación manualmente
Estas limitaciones son deliberadas para mantener la naturaleza declarativa del código IaC, pero requieren diseño cuidadoso de tus workflows de automatización.
Monitoreo de acciones en HCP Terraform
Si utilizas HCP Terraform (anteriormente Terraform Cloud), las ejecuciones de acciones aparecen en el historial del workspace con logs detallados. Esto facilita:
- Auditoría de operaciones del día 2
- Debugging de fallos en triggers automáticos
- Cumplimiento regulatorio con trazabilidad completa
- Integración con sistemas de observabilidad externos
La visibilidad centralizada es crítica para equipos grandes que gestionan múltiples proyectos y necesitan visibilidad unificada de todas las operaciones de infraestructura.
Comparación: Actions vs Provisioners tradicionales
Muchos usuarios veteranos reconocerán similitudes con el recurso terraform_data combinado con provisioners. Las diferencias clave son:
| Característica | Terraform Actions | Provisioners |
|---|---|---|
| Declarativo | Sí | No (imperativo) |
| Idempotencia | Garantizada por provider | Responsabilidad del usuario |
| Manejo de errores | Estandarizado | Inconsistente |
| Soporte multi-cloud | Nativo en providers | Scripts personalizados |
| Integración HCP | Total | Limitada |
HashiCorp recomienda migrar gradualmente de provisioners a acciones para aprovechar mejor el ecosistema moderno del proyecto.
Roadmap futuro y evolución de la feature
Según los anuncios de HashiCorp en HashiConf 2025, las próximas versiones expandirán:
- Soporte para más providers (Azure, GCP, Kubernetes)
- Acciones con outputs parciales para casos específicos
- Integración profunda con Waypoint para deployment pipelines
- Triggers basados en eventos externos (webhooks, mensajes SQS)
- Templates predefinidos para patrones comunes de Day 2 ops
El objetivo a largo plazo es eliminar completamente la necesidad de scripts externos o herramientas adicionales para el ciclo de vida completo de infraestructura.
Preguntas frecuentes sobre Terraform Actions
¿Terraform Actions funciona con versiones anteriores a 1.14?
No, esta característica requiere Terraform 1.14 o superior. Debes actualizar tu versión local y la configuración de tus workspaces en HCP si los utilizas.
¿Puedo usar acciones en módulos reutilizables?
Sí, los autores de módulos pueden definir acciones que los consumidores del módulo pueden invocar. Esto es especialmente útil para operaciones de mantenimiento estandarizadas.
¿Las acciones cuentan contra el límite de recursos de HCP Terraform?
No, las acciones no se contabilizan como recursos gestionados porque no modifican el state. Solo consumen tiempo de ejecución del runner.
¿Qué pasa si una acción falla durante un apply?
El apply completa los cambios de recursos normalmente, pero reporta el error de la acción. Debes decidir manualmente si hacer rollback o corregir el problema y reintentar.
¿Puedo probar acciones en plan sin ejecutarlas realmente?
El comando terraform plan muestra qué acciones se ejecutarían, pero no las invoca realmente. Solo terraform apply ejecuta las acciones configuradas.
