Jugar con Terraform en local con LocalStack

Terraform Actions: Análisis en Profundidad

terraform action

Las Terraform actions representan un nuevo concepto del lenguaje en Terraform 1.14 y fueron anunciadas oficialmente en la HashiConf 2025 en San Francisco. Las Terraform actions se han implementado de forma abierta, por lo que quizá ya las hayas visto aparecer en notas de lanzamiento (tanto de Terraform, como también en providers, language servers, plugins de VS Code, etc.).

En esta breve entrada de blog presentaré qué son las Terraform actions y cómo funcionan. En el camino veremos algunas acciones disponibles del proveedor de AWS que puedes empezar a usar hoy mismo.

En este post solo se habla de las actions en el contexto de una configuración de Terraform y la Terraform CLI. Las actions también están totalmente soportadas en HCP Terraform (para flujos de trabajo con VCS, CLI y API).

Índice

¿Qué son las Terraform actions?

Terraform es, en última instancia, una herramienta para infraestructura como código declarativa. Escribes una configuración que representa el estado deseado de tu infraestructura, y Terraform se asegura de que el mundo real coincida con ese estado deseado. Terraform trabaja en el plano de control, aprovisionando recursos con los que luego puedes interactuar a través de otros medios.

Con las Terraform actions ahora puedes realizar operaciones fuera del flujo normal CRUD (Create-Read-Update-Delete) de Terraform. Permiten operaciones que interactúan con tus recursos de formas en las que normalmente usarías otras herramientas, por ejemplo, Ansible. Ten en cuenta que las Terraform actions no son un reemplazo de Ansible, es más probable que dispares acciones de Ansible (p. ej. ejecutar un playbook) desde Terraform.

CRUD de terraform action

Puedes realizar acciones independientes que se lanzan usando la Terraform CLI, o puedes vincular acciones al ciclo de vida de un recurso.

Ejemplos de acciones disponibles hoy en día son invocar una función AWS Lambda, detener una instancia AWS EC2 e invalidar una caché de AWS CloudFront. Veremos ejemplos de cada una más adelante en esta entrada de blog.

Otra forma de pensar en las Terraform actions es que son una nueva manera declarativa de realizar operaciones que antes habrías implementado con un recurso `terraform_data` junto con un bloque *provisioner* que ejecutaba un script local:

resource "terraform_data" "example" {
  triggers_replace = [
    timestamp(),
  ]

  provisioner "local-exec" {
    command = "scripts/my-script.sh"
  }
}

Las actions son implementadas por los providers, y es probable que al principio la cantidad de acciones disponibles sea limitada.

¿Cómo funcionan las Terraform actions?

Las Terraform actions introducen un nuevo bloque action en el lenguaje de Terraform que puedes usar en tus configuraciones de Terraform. Añades bloques de acción en los mismos archivos .tf que el resto de tu configuración de Terraform.

La sintaxis básica de un bloque de acción es la siguiente:

action "" "" {
  # meta-arguments: provider, count, for_each
  config {
    # action configuration depending on action type
  }
}

Desglose del bloque de acción:

  • El action type representa el tipo de acción tal como está definido en un proveedor de Terraform. Cada nombre de tipo de acción lleva el prefijo del nombre del proveedor, p. ej. la acción aws_lambda_invoke del proveedor de AWS.
  • El symbolic name es similar a cómo se definen los recursos y las fuentes de datos; permite configurar múltiples acciones del mismo tipo de acción siempre que el nombre simbólico sea diferente. Una buena práctica es usar un nombre compuesto por letras minúsculas, números y guiones bajos.
  • El bloque config contiene la configuración de la acción y puede consistir en argumentos y bloques anidados. La configuración será diferente para cada tipo de acción.

Añades bloques de acción a tu configuración de Terraform, y opcionalmente los vinculas al ciclo de vida de tus diferentes recursos. En las siguientes secciones veremos cómo se hace esto.

Cuando ejecutas las operaciones terraform plan y terraform apply, Terraform te informará de qué acciones se dispararán (si hay alguna) y en qué punto del flujo de aprovisionamiento se lanzarán.

Algunas acciones tardarán tiempo en completarse. Terraform esperará hasta que la acción informe de que ha terminado.

Hashicorp Terraform action

Invocar una acción usando la Terraform CLI

Puedes configurar bloques de acción en tu configuración de Terraform que no estén referenciados en ningún otro lugar de tu código. Me referiré a estas acciones como acciones independientes.

Las acciones independientes solo se pueden ejecutar usando la Terraform CLI. Esto se hace añadiendo la bandera -invoke=<action address> a los comandos terraform plan y terraform apply. La dirección de la acción (action address) tiene el formato action.<action type>.<symbolic name>.

La dirección de la siguiente acción es action.aws_lambda_invoke.message:

action "aws_lambda_invoke" "message" {
  config {
    function_name = "send-a-message"
    payload       = jsonencode({
      message = "This is the action payload!"
    })
  }
}

Este es el primer ejemplo concreto de una acción que vemos. La acción aws_lambda_invoke invoca una función Lambda (ninguna sorpresa allí).

Esta acción aws_lambda_invoke tiene muchas opciones de configuración, pero en el caso más simple configuramos qué función invocar (en el argumento function_name) y qué datos pasarle a la función (en el argumento payload). El payload no tiene por qué ser estático como en este ejemplo, puede hacer referencia a variables, valores locales, atributos de recursos, fuentes de datos, y más.

Se espera que la función referenciada en la acción anterior (es decir, la función llamada send-a-message) ya exista.

Podrías aprovisionar un recurso Lambda en la misma configuración de Terraform donde se define la acción y referenciar aws_lambda_function.<symbolic name>.function_name en el argumento function_name de la acción.

Para disparar la acción en el bloque de código anterior usando la Terraform CLI puedes ejecutar este comando:

$ terraform apply \
    -auto-approve \
    -invoke=action.aws_lambda_invoke.message

Terraform will perform the following actions:

Plan: 0 to add, 0 to change, 0 to destroy. Actions: 1 to invoke.

Terraform will invoke the following action(s):

  # action.aws_lambda_invoke.message will be invoked
    action "aws_lambda_invoke" "message" {
        config {
          # truncated for brevity ...
        }
    }

Action started: action.aws_lambda_invoke.message (triggered by CLI)
Action action.aws_lambda_invoke.message (triggered by CLI): Invoking Lambda function slack...
Action action.aws_lambda_invoke.message (triggered by CLI): Lambda function slack invoked successfully (status: 200, payload: 453 bytes)
Action complete: action.aws_lambda_invoke.message (triggered by CLI)

Apply complete! Resources: 0 added, 0 changed, 0 destroyed.

El usuario o entidad que ejecute esta acción debe tener una política AWS IAM que le permita invocar esta función Lambda.

Ten en cuenta que este comando solo ejecuta la acción especificada en la bandera -invoke, nada más en la configuración se aplica o se actualiza (incluyendo recursos y otras acciones).

Solo puedes invocar una única acción a la vez. No puedes añadir banderas adicionales -invoke para disparar múltiples acciones.

Una buena práctica sería primero ejecutar una operación terraform plan para asegurarte de que todo se ve correcto (como harías en cualquier flujo de trabajo de Terraform):

$ terraform plan -invoke=action.aws_lambda_invoke.message

Terraform will perform the following actions:

Plan: 0 to add, 0 to change, 0 to destroy. Actions: 1 to invoke.

Terraform will invoke the following action(s):

  # action.aws_lambda_invoke.message will be invoked
    action "aws_lambda_invoke" "message" {
        config {
          # truncated for brevity ...
        }
    }

Cualquier acción puede ser disparada usando la Terraform CLI, incluso si la vinculas al ciclo de vida de un recurso.

Si tu acción hace referencia a datos que no están disponibles (p. ej. un atributo de un recurso que aún no se ha creado) no podrá ejecutarse como una acción independiente.

Vincular una acción al ciclo de vida de un recurso

Puedes vincular una o más acciones a eventos en el ciclo de vida de un recurso. Esto se logra referenciando la acción desde el bloque lifecycle de un recurso.

Un pseudo-ejemplo de cómo se configura se muestra en el siguiente bloque de código:

resource "" "" {
  # arguments omitted ...

  lifecycle {
    action_trigger {
      events  = []
      actions = [<action(s)>]
    }
  }
}
</action(s)>

Desglose de este ejemplo de código:

  • Dentro del bloque lifecycle de un recurso hay un nuevo bloque soportado: action_trigger.
  • Puedes especificar uno o más eventos que deberían disparar la(s) acción(es) en el argumento events. Los eventos disponibles son before_create, after_create, before_update y after_update.
  • Puedes especificar una o más acciones que deberían dispararse en función de los eventos en el argumento actions. Cada acción se configura usando su dirección, es decir, action.<action type>.<symbolic name>.

Puedes especificar múltiples eventos y múltiples acciones en un bloque action_trigger. También puedes configurar varios bloques action_trigger en el mismo bloque lifecycle de un recurso.

Un ejemplo completo de una acción vinculada al ciclo de vida de una instancia AWS EC2 se muestra a continuación:

action "aws_lambda_invoke" "notifier" {
  config {
    function_name = "notifier"
    payload = jsonencode({
      message = "An EC2 with ID ${aws_instance.web.id} has been created."
    })
  }
}

resource "aws_instance" "web" {
  ami           = "ami-091a906f2e1e40076"
  instance_type = "t3.small"

  tags = {
    Name = "web"
  }

  lifecycle {
    action_trigger {
      events    = [after_create]
      actions   = [action.aws_lambda_invoke.notifier]
    }
  }
}

Como podemos ver, el bloque lifecycle del recurso aws_instance referencia action.aws_lambda_invoke.message. La acción también referencia al recurso aws_instance —¿esto no creará un bucle de dependencias? No, porque la acción se dispara después de que el recurso ha sido creado.

Sin embargo, esto sí significa que esta acción en particular no puede dispararse antes de que el recurso exista, es decir, si intentamos ejecutarla usando la CLI como una acción independiente encontraremos este error:

$ terraform apply -auto-approve -invoke=action.aws_lambda_invoke.message

Error: Action configuration unknown during apply
│
│ The action action.aws_lambda_invoke.message was not fully known during apply.

Disparar una acción condicionalmente

Puedes controlar aún más si una acción se invoca o no usando una expresión de condición dentro del bloque action_trigger. Si la expresión se evalúa como true, la acción será invocada.

Podemos extender el ejemplo anterior para invocar la función Lambda únicamente si la variable llamada send_notifications está configurada como true:

variable "send_notifications" {
  type    = bool
  default = false
}

action "aws_lambda_invoke" "notifier" {
  config {
    function_name = "notifier"
    payload = jsonencode({
      message = "An EC2 with ID ${aws_instance.web.id} has been created."
    })
  }
}

resource "aws_instance" "web" {
  ami           = "ami-091a906f2e1e40076"
  instance_type = "t3.small"

  tags = {
    Name = "web"
  }

  lifecycle {
    action_trigger {
      condition = var.send_notifications
      events    = [after_create]
      actions   = [action.aws_lambda_invoke.notifier]
    }
  }
}

El valor de la expresión en condition debe ser conocido en tiempo de plan. Esto significa que no puedes usar funciones cuyo valor pueda cambiar entre una operación de plan y una de apply (por ejemplo, timestamp()).

Uso de meta-argumentos con Terraform action

Un bloque action soporta los meta-argumentos provider, count y for_each.

El argumento provider permite ejecutar acciones en el contexto de una configuración de proveedor determinada. Como en las configuraciones normales de Terraform, el argumento provider no es obligatorio si solo tienes un proveedor (el proveedor por defecto) de un nombre dado. Si tienes múltiples proveedores con el mismo nombre, puedes usar aliases para diferenciarlos y disparar acciones para cada proveedor:

provider "aws" {
  alias = "dev"
  # ...
}

provider "aws" {
  alias = "prod"
  # ...
}

action "aws_lambda_invoke" "dev" {
  provider = aws.dev
  
  config {
    function_name = "dev-function"
    payload = {
      # ...
    }
  }
}

action "aws_lambda_invoke" "prod" {
  provider = aws.prod
  
  config {
    function_name = "prod-function"
    payload = {
      # ...
    }
  }
}

Los meta-argumentos count y for_each son aún más interesantes. Puedes usar el meta-argumento count para acciones independientes como en el siguiente ejemplo:

action "aws_lambda_invoke" "counter" {
  count = 10

  config {
    function_name = "counter"
    payload       = count.index
  }
}

Esta acción invoca una función Lambda llamada counter que acepta un entero como payload. Se espera que esta función ya exista.

Si invocamos esta acción usando el CLI de Terraform obtenemos el siguiente resultado (nota que la salida se ha truncado para mayor brevedad):

$ terraform apply -auto-approve -invoke=action.aws_lambda_invoke.counter
Terraform will perform the following actions:

Plan: 0 to add, 0 to change, 0 to destroy. Actions: 10 to invoke.

Terraform will invoke the following action(s):

  # action.aws_lambda_invoke.counter[7] will be invoked
    action "aws_lambda_invoke" "counter" {
        config {
            function_name = "counter"
            payload       = "7"
        }
    }

    ...

  # action.aws_lambda_invoke.counter[6] will be invoked
    action "aws_lambda_invoke" "counter" {
        config {
            function_name = "counter"
            payload       = "6"
        }
    }

...
Action started: action.aws_lambda_invoke.counter[4] (triggered by CLI)
... (truncated) ...
Action started: action.aws_lambda_invoke.counter[3] (triggered by CLI)
Action action.aws_lambda_invoke.counter[5] (triggered by CLI): Invoking Lambda function counter...
... (truncated) ...
Action action.aws_lambda_invoke.counter[8] (triggered by CLI): Invoking Lambda function counter...
Action action.aws_lambda_invoke.counter[0] (triggered by CLI): Lambda function counter invoked successfully (status: 200, payload: 4 bytes)
Action complete: action.aws_lambda_invoke.counter[0] (triggered by CLI)
... (truncated) ...
Action action.aws_lambda_invoke.counter[2] (triggered by CLI): Lambda function counter invoked successfully (status: 200, payload: 4 bytes)
Action complete: action.aws_lambda_invoke.counter[2] (triggered by CLI)

Apply complete! Resources: 0 added, 0 changed, 0 destroyed.

El comando anterior disparó todas las instancias de la acción. Podrías disparar una instancia específica usando un selector de índice:

$ terraform apply -auto-approve -invoke='action.aws_lambda_invoke.counter[0]'
...

El meta-argumento for_each permite disparar acciones para cada recurso que también se crea usando for_each. Esto permite asociar un recurso con una acción correspondiente.

Ejemplo de creación de varias instancias EC2 usando for_each y disparando una acción correspondiente para cada recurso EC2:

# definir un valor local para las instancias EC2 que se provisionarán
locals {
  instances = {
    web = {
      ami  = "ami-091a906f2e1e40076"
      size = "t3.small"
    }
    db = {
      ami  = "ami-0bc691261a82b32bc"
      size = "t3.medium"
    }
  }
}

# configurar acciones para cada clave del valor local
# i.e. action.aws_lambda_invoke.slack["web"] y action.aws_lambda_invoke.slack["db"]
action "aws_lambda_invoke" "slack" {
  for_each = local.instances

  config {
    function_name = "slack"

    payload = jsonencode({
      title = "EC2 Instance ${each.key}"
      body  = "Instance ${each.key} has been created/updated with ID: ${aws_instance.servers[each.key].id}"
    })
  }
}

# configurar las instancias EC2 usando for_each con el valor local
# i.e. aws_instance.servers["web"] y aws_instance.servers["db"]
resource "aws_instance" "servers" {
  for_each = local.instances

  ami           = each.value.ami
  instance_type = each.value.size

  tags = {
    Name = each.key
  }

  lifecycle {
    action_trigger {
      # disparar la acción después de la creación inicial
      events  = [after_create]

      # disparar la acción usando la clave del valor local
      # e.g. aws_instance.servers["web"] dispara action.aws_lambda_invoke.slack["web"]
      actions = [action.aws_lambda_invoke.slack[each.key]]
    }
  }
}

Se podría hacer lo mismo usando count, pero usando índices numéricos en lugar de cadenas.

Cadenar múltiples acciones

El bloque lifecycle de un recurso no se limita a invocar una sola acción. Puedes agregar múltiples acciones dentro de un mismo bloque action_trigger e incluso añadir bloques action_trigger adicionales.

Las acciones que deben ejecutarse después del mismo evento (por ejemplo, after_create) se pueden agrupar en el mismo bloque action_trigger. Un ejemplo de disparar tres acciones diferentes (invocando tres funciones Lambda distintas) después de crear una instancia EC2 se puede configurar así:

action "aws_lambda_invoke" "first" {
  config {
    function_name = "first"
    payload       = jsonencode({
      # ...
    })
  }
}

action "aws_lambda_invoke" "second" {
  config {
    function_name = "second"
    payload       = jsonencode({
      # ...
    })
  }
}

action "aws_lambda_invoke" "third" {
  config {
    function_name = "third"
    payload       = jsonencode({
      # ...
    })
  }
}

resource "aws_instance" "web" {
  ami           = "ami-091a906f2e1e40076"
  instance_type = "t3.small"

  lifecycle {
    action_trigger {
      events = [after_create]
      actions = [
        action.aws_lambda_invoke.first,
        action.aws_lambda_invoke.second,
        action.aws_lambda_invoke.third,
      ]
    }
  }
}

Se puede lograr lo mismo usando tres bloques action_trigger separados:

resource "aws_instance" "servers" {
  ami           = "ami-091a906f2e1e40076"
  instance_type = "t3.small"

  tags = {
    Name = "web"
  }

  lifecycle {
    action_trigger {
      events = [after_create]
      actions = [
        action.aws_lambda_invoke.first,
      ]
    }

    action_trigger {
      events = [after_create]
      actions = [
        action.aws_lambda_invoke.second,
      ]
    }

    action_trigger {
      events = [after_create]
      actions = [
        action.aws_lambda_invoke.third,
      ]
    }
  }
}

Por brevedad, se recomienda usar el primer ejemplo (combinar las acciones disparadas por el mismo tipo de evento en un solo bloque action_trigger).

Si tienes diferentes conjuntos de acciones para distintos tipos de eventos, debes usar un bloque action_trigger para cada tipo de evento:

resource "aws_instance" "web" {
  ami           = "ami-091a906f2e1e40076"
  instance_type = "t3.small"

  lifecycle {
    action_trigger {
      events = [before_create]
      actions = [
        action.aws_lambda_invoke.first,
      ]
    }

    action_trigger {
      events = [after_create]
      actions = [
        action.aws_lambda_invoke.first,
        action.aws_lambda_invoke.second,
      ]
    }

    action_trigger {
      events = [before_update]
      actions = [
        action.aws_lambda_invoke.second,
      ]
    }

    action_trigger {
      events = [after_update]
      actions = [
        action.aws_lambda_invoke.second,
        action.aws_lambda_invoke.third,
      ]
    }
  }
}

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.

Dependiendo del resultado de una acción

En el momento de escribir esto, parece que no hay soporte para depender del resultado de una acción. Esto significa que no puedes hacer algo así:

 action "aws_lambda_invoke" "dummy" { config { # ... } } resource "..." "..." { # argumentos omitidos ... depends_on = [ action.aws_lambda_invoke.dummy, ] }

La razón más probable es que el resultado de la acción no puede conocerse de antemano por Terraform en el momento del plan.

Otra cosa que podrías intentar es depender de un recurso que esté vinculado a una acción determinada, algo como esto:

 action "aws_lambda_invoke" "dummy" { config { # ... } } resource "aws_instance" "dummy" { # argumentos omitidos ... lifecycle { action_trigger { events = [after_create] actions = [action.aws_lambda_invoke.dummy] } } } resource "aws_s3_bucket" "dummy" { # argumentos omitidos ... depends_on = [ aws_instance.dummy, ] }

Sin embargo, una vez que la instancia EC2 (aws_instance.dummy) se provisiona, se dispara la acción (aws_lambda_invoke.dummy) y la creación del bucket S3 (aws_s3_bucket.dummy) empieza en paralelo. No hay garantía de que la acción haya terminado antes de que comience el siguiente recurso.

En resumen: no puedes depender del resultado de una acción en código Terraform posterior; Terraform solo puede esperar a que los recursos existan, pero no a que las acciones terminen.

Puntos clave

Las acciones de Terraform te permiten extender tus configuraciones de Terraform con operaciones que van más allá de las acciones CRUD normales sobre tus recursos. Las acciones de Terraform representan operaciones declarativas que puedes ejecutar como acciones independientes o vincularlas al ciclo de vida de un recurso.

En esta publicación del blog aprendimos qué son las acciones, cómo funcionan y vimos algunos ejemplos de acciones disponibles en el proveedor de AWS para Terraform.

Las acciones se configuran usando el nuevo bloque action. Puedes invocar acciones independientes usando terraform action -invoke=<dirección de=»» la=»» acción=»»>. El bloque lifecycle de un recurso ahora soporta un nuevo bloque action_trigger donde puedes vincular acciones al ciclo de vida del recurso.

Creo que veremos mucho “action” (juego de palabras intencionado) en el mundo de las acciones de Terraform en el futuro.

Aprender más

  1. Creo que es importante mencionar esto porque la otra nueva característica importante de Terraform es Terraform search, que incluye el nuevo bloque `list`. Sin embargo, los bloques `list` se configuran en archivos `.tfquery.hcl` y **no forman parte de la configuración normal de Terraform**.

</dirección>

Artículo original: Terraform Actions: Deep-Dive

Más apuntes

Invítame a un café con bitcoins:
1QESjZDPxWtZ9sj3v5tvgfFn3ks13AxWVZ

Bitcoins para café
También puedes invitarme a algo para mojar...

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Rellena este campo
Rellena este campo
Por favor, introduce una dirección de correo electrónico válida.
Tienes que aprobar los términos para continuar