Resource terraform_data

terraform_data is a managed resource in the Terraform, which will undergo a standard resource lifecycle of create, update, and delete. Unlike other resources, it does not perform any actual actions or interactions with infrastructure. terraform_data does not need a provider to configure it because, quite simply, it does not interact with external services and hence, no provider is needed.
terraform_data is allows you to store values, and also it can be used for triggering provisioners. Provisioners are the special blocks in Terraform that execute arbitrary code or scripts during the terraform apply. Normally, provisioners are attached to a managed resource, such as a virtual machine or a database instance. Sometimes, you might want to run a provisioner, but there isn't any logical managed resource where to attach it. That's where terraform_data comes in.

terraform_data Attributes

The following arguments are supported:

Usecases of terraform_data Attributes

There are three primary use cases that the terraform_data serves:

Scenario 1: Replacing a Resource when Changes Occur in a Terraform Variable

The replace_triggered_by lifecycle argument changes the resource when any attribute in another resource changes. However, there are a few scenarios you might want to mark a resource for replacement when a Terraform variable which could be input, output or local variable changes.
For this purpose, terraform_data comes in handy. terraform_data allows to create a proxy resource that tracks the change of a Terraform variable. The proxy resource can then be used in the replace_triggered_by lifecycle argument to trigger the replacement of another resource.
For example, let's say you have a Terraform variable revision and you wanted to replace a example_database resource whenever the revision variable changes:
variable "revision" {
    default = 1
}
resource "terraform_data" "replacement_trigger" {
    input = var.revision
}
resource "aws_s3_bucket" "test" {
    lifecycle {
        replace_triggered_by = [terraform_data.replacement]
    }
}
Here, in the above example, the replacement_trigger of the terraform_data resource is tracking for changes to the revision variable. On changing the revision variable, the replacement_trigger of the terraform_data resource will be renewed and in turn, trigger the replacement of the aws_s3_bucket resource named test.

Scenario 2: Running Provisioners without Attaching to any Resource

In general, a provisioner in Terraform is used to run scripts or execute commands on a resource after it is created. Provisioners are attached to a resource, and they run when the resource is created or changed.
However, there are those situations where you may want to execute a provisioner without being attached to a resource, because provisioner itself doesn't depend on a resource. Here is where terraform_data comes in. The terraform_data allows you to create a resource that can run the provisioner without attaching it to any resource.
resource "terraform_data" "provisioner_wrapper" {
    provisioner "local-exec" {
        command = "echo 'Hello, world!' > hello.txt"
    }
}
Here, we define a terraform_data resource called "provisioner_wrapper". This will contain the provisioner section local-exec which executes a command to write "Hello, world!" to a file called "hello.txt". The important thing to note here is that this provisioner isn't attached to any resource and runs independently.

Scenario 3: Running Provisioners when any of the resource attribute changes

Imagine you have a resource created in your state, which has a lot of attributes. For example, a virtual machine can have cpu_count, memory_size, and disk_size. In this case, whenever you change just one of them, the provisioner won't be run because it is only triggered on the create or update events, not on attribute updates.
One way to overcome this limitation is the use of triggers_replace with terraform_data in order to run a provisioner when any of the resource attributes change. triggers_replace in Terraform is a special argument that enables you to specify under what conditions you want the provisioner to run.
resource "aws_instance" "instance" {
    ami = "ami-0123456789"
    instance_type = "t2.micro"
    cpu_options = {
        core_count = 2
        threads_per_core = 2
    }
}
resource "terraform_data" "provisioner_wrapper" {
    triggers_replace = {
        cpu_count = aws_instance.instance.instance_type
        memory_size = aws_instance.instance.cpu_options.core_count
        disk_size = aws_instance.instance.cpu_options.threads_per_core
    }
    provisioner "local-exec" {
        command = "echo 'Attribute changed!' > attribute_changed.txt"
    }
}
Here, in the above example, we have created a terraform_data resource with a trigger_replace block. The trigger_replace block specifies the attributes to watch that will trigger the running of the provisioner. In our case, we monitor the instance_type, core_count, and threads_per_core attributes of an aws_instance resource. If any of these attributes change, the provisioner runs, executing a command to write "Attribute changed!" to a file called attribute_changed.txt.

Related Pages

Feedback

Was this page helpful?