Skip to main content

Terraform Actions: Deep-Dive

·3910 words·19 mins
Terraform Actions Aws Hashiconf

Terraform actions represent a new language concept in Terraform 1.14 and they were officially announced at HashiConf 2025 in San Francisco. Terraform actions have been implemented in the open, so you might have already seen them appear in release notes (both for Terraform, but also in providers, language servers, VS Code plugins, etc).

In this short blog post I will introduce what Terraform actions are and how they work. Along the way we will see a few available actions from the AWS provider that you can start using today.

In this blog post I only discuss actions in the context of a Terraform configuration and the Terraform CLI. Actions are also fully supported on HCP Terraform (for VCS, CLI, and API workflows).

What are Terraform actions?
#

Terraform is ultimately a tool for declarative infrastructure-as-code. You write a configuration representing the desired state of your infrastructure, and Terraform makes sure the real world matches your desired state. Terraform works at the control plane, provisioning resources that you can then interact with through some other means.

With Terraform actions you can now perform operations outside of the normal CRUD (Create-Read-Update-Delete) workflow of Terraform. Enabling operations that interact with your resources in ways you normally use other tools for, e.g. Ansible. Note that Terraform actions are not a replacement for Ansible, it is more likely that you will trigger Ansible actions (e.g. run a playbook) from Terraform.

You can perform standalone actions that you trigger using the Terraform CLI, or you can bind actions to the lifecycle of a resource.

Examples of actions that are available today are invoking an AWS Lambda function, stopping an AWS EC2 instance, and invalidating an AWS CloudFront cache. We will see examples of each of these later in this blog post.

Another way to think about Terraform actions is that it’s a new declarative way to perform operations that you would previously use a terraform_data resource for along with a provisioner block that triggers a local script:

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

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

Actions are implemented by providers, and it is likely that the amount of available actions will be sparse in the beginning.

How do Terraform actions work?
#

Terraform actions introduce a new action block to the Terraform language that you can use in your Terraform configurations. You add action blocks to the same .tf files as the rest of your Terraform configuration1.

The basic syntax of an action block is the following:

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

A breakdown of the action block:

  • The <action type> represents the type of action as defined in a Terraform provider. Each action type name is prefixed with the name of the provider, e.g. the aws_lambda_invoke action from the AWS provider.
  • The <symbolic name> is similar to how resources and data sources are defined, they allow you to configure multiple actions of the same action type as long as the symbolic name is different. A good practice is to use a name consisting of lowercase letters, numbers, and underscores.
  • The config block contains the configuration of the action and could consist of arguments and nested blocks. The configuration will be different for each action type.

You add action blocks to your Terraform configuration, and optionally bind them to the lifecycle of your different resources. In the following sections we will see how this is done.

When you run terraform plan and terraform apply operations Terraform will inform you of what actions will be triggered (if any) and at what point in the provisioning workflow the actions will be triggered.

Some actions will take time to complete. Terraform will wait until the action reports back that it is done.

Invoke an action using the Terraform CLI
#

You can configure action blocks in your Terraform configuration that are not referenced anywhere else in your code. I will refer to these actions as standalone actions.

Standalone actions can only be triggered using the Terraform CLI. This is done by adding the -invoke=<action address> flag to the terraform plan and terraform apply commands. The <action address> has the format action.<action type>.<symbolic name>.

The address of the following action is action.aws_lambda_invoke.message:

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

This is the first concrete example of an action that we see. The aws_lambda_invoke action invokes a Lambda function (no surprise there).

This aws_lambda_invoke action has many configuration options, but in the simplest case we configure which function to invoke (in the function_name argument) and what data to pass to the function (in the payload argument). The payload does not have to be static as in this example, it can reference variables, local values, resource attributes, data sources, and so on.

The function referenced in the previous action (i.e. the function named send-a-message) is expected to already exist.

You could provision a Lambda resource in the same Terraform configuration where the action is configured and reference aws_lambda_function.<symbolic name>.function_name in the function_name argument of the action.

To trigger the action in the previous code block using the Terraform CLI you can run this command:

$ 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.
The user or entity running this action must have an AWS IAM policy that allows it invoke this Lambda function.

Note that this command only triggers the action specified in the -invoke flag, nothing else in the configuration is applied or updated (including resources and other actions).

You can only invoke a single action at a time. You can’t add additional -invoke flags to trigger multiple actions.

A good practice would be to first run a terraform plan operation to make sure everything looks OK (as you would do for all Terraform workflows):

$ 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 ...
        }
    }

Any action can be triggered using the Terraform CLI, even if you bind it to the lifecycle of a resource.

If your action references data that is not available (e.g. an attribute from a resource that has not been created) it will not be able to run as a standalone action.

Bind an action to the lifecycle of a resource
#

You can bind one or more actions to events in the lifecycle of a resource. This is achieved by referencing the action from the lifecycle block of a resource.

A pseudo example of how this is configured is shown in the following code block:

resource "<resource type>" "<symbolic name>" {
  # arguments omitted ...

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

A breakdown of this code sample:

  • Inside of the lifecycle block of a resource there is a new supported block: action_trigger.
  • You can specify one or more events that should trigger the action(s) in the events argument. Available events are before_create, after_create, before_update, and after_update.
  • You can specify one or more actions that should be triggered based on the events in the actions argument. Each action is configured using its address, i.e. action.<action type>.<symbolic name>.

You can specify multiple events and multiple actions in an action_trigger block. You can also configure multiple action_trigger blocks in the same resource lifecycle block. See Chain multiple actions together later in this blog post for examples of how this works.

A full example of an action that is bound to the lifecycle of an AWS EC2 instance is shown below:

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]
    }
  }
}

As we can see, the lifecycle block of the aws_instance resource references action.aws_lambda_invoke.message. The action references the aws_instance resource as well - won’t this create a dependency loop? No, because the action is triggered after the resource has been created.

However, this does mean that this particular action can’t be triggered before the resource exists, i.e. if we try to trigger it using the CLI as a standalone action we encounter this 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.

Conditionally trigger an action
#

You can further control if an action is invoked or not using a condition expression inside of the action_trigger block. If the expression evaluates to true, the action will be invoked.

We can extend the previous example to only invoke the Lambda function if the variable named send_messages is set to 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]
    }
  }
}

The expression value of the condition must be a known value at plan time. This means you can’t use function values that could change between a plan and apply operation (e.g. timestamp()).

Using meta-arguments with actions
#

An action block supports the provider, count and for_each meta-arguments.

The provider argument allows you to run actions in the context of a given provider configuration. As with normal Terraform configurations the provider argument is not required if you only have a single provider (the default provider) of a given name. If you have multiple providers of the same name you can use aliases to differentiate them and trigger actions for each provider:

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 = {
      # ...
    }
  }
}

The count and for_each meta-arguments are more interesting. You can use the count meta-argument for stand-alone actions like in the following example:

action "aws_lambda_invoke" "counter" {
  count = 10

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

This action invokes a Lambda function named counter that accepts an integer as payload. This function is expected to already exist.

If we invoke this action using the Terraform CLI we get the following result (note that the output is truncated for brevity):

$ 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.

The previous command triggered all instances of the action. You could trigger a specific instance using an index selector:

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

The for_each meta-argument allows you to trigger actions for each resource that is also created using the for_each meta argument. This means you can match a resource with a corresponding action.

An example of creating a number of EC2 instances using for_each and invoking a corresponding action for every EC2 resource:

# define a local value for EC2 instances that will be provisioned
locals {
  instances = {
    web = {
      ami  = "ami-091a906f2e1e40076"
      size = "t3.small"
    }
    db = {
      ami  = "ami-0bc691261a82b32bc"
      size = "t3.medium"
    }
  }
}

# configre actions for each key from the local value
# i.e. action.aws_lambda_invoke.slack["web"] and 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}"
    })
  }
}

# configure the EC2 instances using for_each with the local value
# i.e. aws_instance.servers["web"] and 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 {
      # trigger the action after the initial create
      events  = [after_create]

      # trigger the action using the key from the local value
      # e.g. aws_instance.servers["web"] triggers action.aws_lambda_invoke.slack["web"]
      actions = [action.aws_lambda_invoke.slack[each.key]]
    }
  }
}

You could do the same thing using count but use numeric indices instead of strings.

Chain multiple actions together
#

The lifecycle block of a resource is not limited to invoking a single action. You can add multiple actions for each action_trigger block, and you can even add additional action_trigger blocks.

Actions that should be performed after the same event (e.g. after_create) can be grouped in the same action_trigger block. An example of triggering three different actions (invoking three different Lambda functions) after an EC2 instance has been created can be configured like this:

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,
      ]
    }
  }
}

You can achieve the same thing using three separate action_trigger blocks:

# previous code omitted ...
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,
      ]
    }
  }
}

For brevity you should favor the first example (combining actions triggered by the same event type in the same action_trigger block).

If you have different sets of actions for different event types you must use one action_trigger block for each event type:

# previous code omitted ...

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,
      ]
    }
  }
}

Long-running actions
#

The aws_lambda_invoke action that we have seen a few times in this blog post generally executes quickly. This assumes the Lambda function is fairly simple. What does the experience look like for long-running actions?

The AWS provider has an action for stopping EC2 instances gracefully. This could be useful if you want to provision EC2 instances and configure them (e.g. through userdata scripts) but intend to leave them stopped until a later time.

In the following example we use a local value (named instances) to configure settings for two different EC2 instances. We then use this local value in a for_each together with the aws_instance resource type. In the lifecycle block of the EC2 instances we specify that the aws_ec2_stop_instance.all[each.key] action should be invoked after the instance has been created (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]]
    }
  }
}

If you run terraform apply for this Terraform configuration you will see how the action is triggered for each EC2 instance, and Terraform then polls the state of the EC2 instance until it reports back that it is stopped (the output only shows the db instance for brevity):

$ 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 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 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 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 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 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 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"])

It should be mentioned that there is a resource in the AWS provider that allows you to set the state of an EC2 instance:

resource "aws_ec2_instance_state" "test" {
  instance_id = aws_instance.test.id
  state       = "stopped"
}

The benefit of the aws_ec2_stop_instance action is that it will gracefully stop the instance. This is not true for the aws_ec2_instance_state resource.


Another action that could potentially take some time to execute is to invalidate a CloudFront cache. The aws_cloudfront_create_invalidation action is available to perform this action.

In the following Terraform configuration we create an AWS CloudFront distribution with an S3 origin. We add an index.html page to the S3 bucket. If the index.html page is updated we want to invalidate the CloudFront cache so that the new HTML content is displayed to users directly. The full example is out of scope for this blog post, but the relevant configuration is shown below:

# create the index.html object in the S3 bucket
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 {
      # trigger an invalidation action after this object is updated
      events  = [after_update]

      # invoke the cloudfront action
      actions = [action.aws_cloudfront_create_invalidation.update]
    }
  }
}

action "aws_cloudfront_create_invalidation" "update" {
  config {
    distribution_id = aws_cloudfront_distribution.default.id

    # control which paths are invalidated, or use "/*" for all paths
    paths           = ["/*"]
  }
}

At the initial terraform apply no action will be invoked. Updating the contents of index.html and running a new terraform plan gives the following results:

$ 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.

One action will be invoked. Applying this plan:

$ 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.

Since the S3 bucket only contains a single HTML file this action executes fairly quickly.

Depending on the outcome of an action
#

At the time of writing there does not seem to be support for depending on the outcome of an action. This means you can’t do something like this:

action "aws_lambda_invoke" "dummy" {
  config {
    # ...
  }
}

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

  depends_on = [
    action.aws_lambda_invoke.dummy,
  ]
}

The reason for this is most likely because the result of the action invocation cannot be known by Terraform in-advance at plan time.

Another thing you might try is to depend on a resource that is bound to a given action, something like this:

action "aws_lambda_invoke" "dummy" {
  config {
    # ...
  }
}

resource "aws_instance" "dummy" {
  # arguments omitted ...

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

resource "aws_s3_bucket" "dummy" {
  # arguments omitted ...

  depends_on = [
    aws_instance.dummy,
  ]
}

However, once the EC2 instance (aws_instance.dummy) is provisioned it will trigger the action (aws_lambda_invoke.dummy) and start provisioning the S3 bucket (aws_s3_bucket.dummy) in parallel.

So in summary: you can’t depend on the outcome of an action in subsequent Terraform code.

Key Takeaways
#

Terraform actions allow you to extend your Terraform configurations with actions that go outside of the normal CRUD operations on your resources. Terraform actions represent declarative operations that you can perform as stand-alone actions or you can bind them to the lifecycle of a resource.

In this blog post we learned what actions are, how they work, and we saw a few examples of actions available in the AWS provider for Terraform.

Actions are configured using the new action block. You can invoke stand-alone actions using terraform action -invoke=<action address>. The lifecycle block of a resource now supports a new action_trigger block where you can bind actions to the lifecycle of the resource.

I believe we will see a lot of action (pun intended) in the Terraform action space going forward.

Learn more
#


  1. I think that it is important to mention this because the other major new feature of Terraform is Terraform search that includes the new list block. However, list blocks are configured in .tfquery.hcl files and are not part of the normal Terraform configuration. ↩︎

Mattias Fjellström
Author
Mattias Fjellström
Cloud architect · Author · HashiCorp Ambassador · Microsoft MVP