Acciones de larga duración
La acción aws_lambda_invoke
que hemos visto varias veces generalmente se ejecuta rápidamente, asumiendo que la función Lambda es relativamente simple. Pero, ¿cómo es la experiencia para acciones que tardan más en ejecutarse?
El proveedor de AWS tiene una acción para detener instancias EC2 de forma segura. Esto puede ser útil si deseas aprovisionar instancias EC2 y configurarlas (por ejemplo, mediante scripts de userdata
) pero dejar las instancias detenidas hasta un momento posterior.
En el siguiente ejemplo usamos un valor local (instances
) para configurar dos instancias EC2 diferentes y luego usamos este valor en un for_each
junto con el recurso aws_instance
. En el bloque lifecycle
especificamos que la acción aws_ec2_stop_instance.all[each.key]
se ejecute después de crear la instancia (events = [after_create]
):
locals {
instances = {
web = {
ami = "ami-091a906f2e1e40076"
size = "t3.small"
}
db = {
ami = "ami-0bc691261a82b32bc"
size = "t3.medium"
}
}
}
action "aws_ec2_stop_instance" "all" {
for_each = local.instances
config {
instance_id = aws_instance.servers[each.key].id
}
}
resource "aws_instance" "servers" {
for_each = local.instances
ami = each.value.ami
instance_type = each.value.size
tags = {
Name = each.key
}
lifecycle {
action_trigger {
events = [after_create]
actions = [action.aws_ec2_stop_instance.all[each.key]]
}
}
}
Al ejecutar terraform apply
para esta configuración, verás cómo la acción se dispara para cada instancia EC2, y Terraform sigue el estado de la instancia hasta que se detiene:
$ terraform apply
...
Action action.aws_ec2_stop_instance.all["db"] (triggered by aws_instance.servers["db"]): EC2 instance i-006c09cd899162829 is currently in state 'stopping', continuing to wait for 'stopped'...
Action action.aws_ec2_stop_instance.all["db"] (triggered by aws_instance.servers["db"]): EC2 instance i-006c09cd899162829 has been successfully stopped
Action complete: action.aws_ec2_stop_instance.all["db"] (triggered by aws_instance.servers["db"])
Existe un recurso en el proveedor AWS que permite establecer directamente el estado de una instancia EC2:
resource "aws_ec2_instance_state" "test" {
instance_id = aws_instance.test.id
state = "stopped"
}
La ventaja de la acción aws_ec2_stop_instance
es que detiene la instancia de manera segura, cosa que no garantiza aws_ec2_instance_state
.
Otra acción que puede tardar en ejecutarse es invalidar la caché de CloudFront. La acción aws_cloudfront_create_invalidation
permite realizar esta tarea.
En el siguiente ejemplo creamos una distribución de CloudFront con un origen S3. Añadimos una página index.html
al bucket S3. Si se actualiza el archivo, queremos invalidar la caché de CloudFront para que los usuarios vean el contenido actualizado:
resource "aws_s3_object" "index_html" {
bucket = aws_s3_bucket.default.bucket
key = "index.html"
content_type = "text/html"
content_base64 = filebase64("${path.module}/html/index.html")
lifecycle {
action_trigger {
events = [after_update]
actions = [action.aws_cloudfront_create_invalidation.update]
}
}
}
action "aws_cloudfront_create_invalidation" "update" {
config {
distribution_id = aws_cloudfront_distribution.default.id
paths = ["/*"]
}
}
Al ejecutar un terraform apply
inicial, no se invoca ninguna acción. Tras actualizar index.html
y correr un nuevo plan:
$ terraform plan
# ...
Terraform will perform the following actions:
# aws_s3_object.index_html will be updated in-place
~ resource "aws_s3_object" "index_html" {
~ content_base64 = "..." # truncated
id = "actions20250921153319508800000001/index.html"
tags = {}
+ version_id = (known after apply)
# (25 unchanged attributes hidden)
}
# Actions to be invoked after this change in order:
action "aws_cloudfront_create_invalidation" "update" {
config {
distribution_id = "E1ATESYZBVWG3G"
paths = [
"/*",
]
}
}
Plan: 0 to add, 1 to change, 0 to destroy. Actions: 1 to invoke.
Aplicando este plan, Terraform ejecuta la invalidación de la caché de CloudFront:
$ terraform apply
# ...
aws_s3_object.index_html: Modifying... [id=actions20250921153319508800000001/index.html]
aws_s3_object.index_html: Modifications complete after 1s [id=actions20250921153319508800000001/index.html]
Action started: action.aws_cloudfront_create_invalidation.update (triggered by aws_s3_object.index_html)
Action action.aws_cloudfront_create_invalidation.update (triggered by aws_s3_object.index_html): Starting cache invalidation for CloudFront distribution E1ATESYZBVWG3G...
Action action.aws_cloudfront_create_invalidation.update (triggered by aws_s3_object.index_html): Creating invalidation request for 1 path(s)...
Action action.aws_cloudfront_create_invalidation.update (triggered by aws_s3_object.index_html): Invalidation IDFZHCUYBIIM0TTA0LX0ICX0M5 created, waiting for completion...
Action action.aws_cloudfront_create_invalidation.update (triggered by aws_s3_object.index_html): CloudFront cache invalidation IDFZHCUYBIIM0TTA0LX0ICX0M5 completed successfully for distribution E1ATESYZBVWG3G
Action complete: action.aws_cloudfront_create_invalidation.update (triggered by aws_s3_object.index_html)
Apply complete! Resources: 0 added, 1 changed, 0 destroyed.
Como el bucket solo contiene un archivo HTML, la acción se ejecuta rápidamente.