OpenTofu: A Beginners Guide to a Terraform Fork Including Migration From Terraform

Getting Started with OpenTofu

Update and Destroy Infrastructure

In this tutorial, you’ll learn how to update and destroy infrastructure managed by OpenTofu using a simple local_file example. We’ll walk through modifying resource configuration, previewing changes, applying updates, tearing down resources, and organizing your .tf files for maintainability.


🔄 Updating a Resource

To change an existing local_file resource, edit its configuration. In this example, we add the file_permission argument and set it to "0700":

resource "local_file" "pet" {
  filename        = "/root/pets.txt"
  content         = "We love pets!"
  file_permission = "0700"
}

Next, preview the plan with:

tofu plan

Output (truncated):

local_file.pet: Refreshing state... [id=cba595b7d9f94ba11074a6f3f731912d95fb3d2c]
OpenTofu used the selected providers to generate the following execution plan.
Resource actions are indicated with these symbols:
  -/+ destroy and then create replacement

  # local_file.pet must be replaced
  -/+ resource "local_file" "pet" {
      ~ file_permission = "0777" -> "0700" # forces replacement
      ~ id              = "cba595b7d9f94ba11074a6f3f731912d95fb3d2c" -> (known after apply)
      ... (other attributes hidden)
    }

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

Note: You didn't use the `-out` option to save this plan, so OpenTofu can’t guarantee to take exactly these actions if you run `tofu apply` now.

Tip

Save your plan with tofu plan -out=plan.tfplan to lock in the exact changes for later application.

Understanding the Plan Output

  • The -/+ indicator shows the resource will be destroyed and recreated.
  • # forces replacement highlights why OpenTofu must rebuild the resource—in this case, due to a permission change.
  • The summary line (e.g., 1 to add, 0 to change, 1 to destroy) gives a quick overview of the plan.

✅ Applying the Update

To apply the pending changes, run:

tofu apply

You’ll see the same plan, then a confirmation prompt:

Do you want to perform these actions?
  # local_file.pet must be replaced
Enter a value: yes

local_file.pet: Destroying... [id=...]
local_file.pet: Creation complete after 0s

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

🗑️ Destroying a Resource

When you no longer need the local_file resource, use:

tofu destroy

Example output:

local_file.pet: Refreshing state... [id=...]
OpenTofu used the selected providers to generate the following execution plan.
Resource actions are indicated with:
  - destroy

  # local_file.pet will be destroyed
  - resource "local_file" "pet" {
      - content         = "We love pets!" -> null
      - file_permission = "0700"            -> null
      - filename        = "/root/pets.txt"  -> null
      - id              = "..."             -> null
      ... (other attributes hidden)
    }

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

Do you really want to destroy all resources?
Enter a value: yes

local_file.pet: Destroying... [id=...]
local_file.pet: Destruction complete after 0s

Destroy complete! Resources: 1 destroyed.

Warning

Adding -auto-approve skips all confirmation prompts. Use with caution, as it will immediately destroy your managed resources.


🗂️ Organizing Configuration Files

OpenTofu loads all .tf files in the working directory. Splitting configurations into multiple files can enhance readability and maintainability.

For example, a directory with two resources:

[opentofu-local-file]$ ls /root/opentofu-local-file
local.tf  cat.tf
FileDescription
local.tfDefines the pet local_file resource
cat.tfDefines the cat local_file resource

local.tf

resource "local_file" "pet" {
  filename = "/root/pets.txt"
  content  = "We love pets!"
}

cat.tf

resource "local_file" "cat" {
  filename = "/root/cat.txt"
  content  = "My favorite pet is Mr. Whiskers"
}

When you run tofu apply, both resources are created together.

Single vs. Multiple Files

Alternatively, you can combine all resources in one main.tf:

resource "local_file" "pet" {
  filename = "/root/pets.txt"
  content  = "We love pets!"
}

resource "local_file" "cat" {
  filename = "/root/cat.txt"
  content  = "My favorite pet is Mr. Whiskers"
}

As your project grows, consider splitting into:

  • variables.tf
  • outputs.tf
  • providers.tf
  • main.tf

This structure improves clarity and makes collaboration easier.


Watch Video

Watch video content

Previous
Installing OpenTofu and HashiCorp Configuraton Language HCL Basics