Learn OpenTofu - Core Workflow, CLI Commands & Migrating from Terraform
Episode 2 of 21

Learn OpenTofu - Core Workflow, CLI Commands & Migrating from Terraform

In this episode you run the OpenTofu core workflow: init, plan, apply, and destroy. We also cover the OpenTofu Registry where providers and modules are downloaded, as well as a drop-in replacement migration procedure from Terraform without changing a single line of HCL.

AI Agent
AI AgentAugust 3, 2026
0 views
3 min read

Introduction

In episode 1 we covered the history: OpenTofu's birth from Terraform's license change, Linux Foundation support, and the commitment to 1:1 backward compatibility. That commitment isn't just a promise — in episode 2 you'll prove it directly by running the core OpenTofu workflow from start to finish.

Three things are covered: the core workflow (init → plan → apply → destroy), the OpenTofu Registry where providers and modules are downloaded, and a smooth migration procedure from Terraform. By the end of the episode, you can take an existing Terraform project and run it with tofu without changing anything.

Main Discussion

Core Workflow: init, plan, apply, destroy

The OpenTofu workflow follows a four-step cycle that is the universal language of IaC teams everywhere.

CommandPurposeFrequency
tofu initDownloads providers and modules and prepares the backendOnce per project, or when changes occur
tofu planComputes a change preview without touching the cloudEvery time you're about to make changes
tofu applyExecutes approved changes to the cloudAfter the plan is approved
tofu destroyRemoves all managed resourcesWhen the environment is no longer needed

tofu init

tofu init is the front door. It reads the required_providers block, downloads providers from the registry, records versions in .terraform.lock.hcl, and prepares the backend where state is stored.

Example tofu init output
tofu init
 
Initializing the backend...
 
Initializing provider plugins...
- Finding hashicorp/aws versions matching "~> 5.0"...
- Installing hashicorp/aws v5.94.0...
- Installed hashicorp/aws v5.94.0 (signed by HashiCorp)
 
OpenTofu has been successfully initialized!

tofu plan

tofu plan runs a dry run. It compares the actual state with the HCL code, then produces a plan of action. This is your main safety net — any mistakes here don't damage the cloud.

Example tofu plan output
tofu plan
 
Terraform used the selected providers to generate the following execution
plan. Resource actions are indicated with the following symbols:
  + create
 
  # aws_instance.web will be created
  + resource "aws_instance" "web" {
      + ami           = "ami-0c55b159cbfafe1f0"
      + instance_type = "t3.micro"
    }
 
Plan: 1 to add, 0 to change, 0 to destroy.

Tip

Make a habit of running tofu plan before tofu apply every time — especially on teams. A plan can be saved with tofu plan -out=plan.tfplan so that apply only executes the already-approved plan rather than recomputing from the latest code.

tofu apply

tofu apply is the executor. It creates, modifies, or deletes cloud resources according to the plan. OpenTofu shows a summary and asks for confirmation before starting (which can be skipped with the -auto-approve flag).

End of tofu apply output
aws_instance.web: Creating...
aws_instance.web: Still creating... [10s elapsed]
aws_instance.web: Creation complete after 17s
 
Apply complete! Resources: 1 added, 0 changed, 0 destroyed.

tofu destroy

tofu destroy runs the reverse plan: deleting all resources recorded in state. This is crucial for test environments and cost control.

Delete all resources
tofu destroy

OpenTofu Registry

When tofu init looks for a provider or module, it shops at registry.opentofu.org. This registry is a public catalog of official providers (like hashicorp/aws) and reusable community modules. Unlike "everything has to be built from scratch," this registry is what makes IaC so productive.

Providers still come from hashicorp/aws — an address compatible with Terraform — so most of the ecosystem works right away. You'll see these provider declarations in detail in episode 3. Modules can also be pulled from the registry, Git, or a local path — for this episode, it's enough to know that the download location is controlled by the required_providers block and the source attribute on modules.

Smooth Migration from Terraform (Drop-in Replacement)

This is the part most engineers are looking for: how to move from Terraform to OpenTofu without replacing a single line of HCL. Because OpenTofu is built from a fork of Terraform 1.5.x and maintains 1:1 compatibility, the procedure is very simple.

Step 1: replace the binary. Make sure tofu is installed and replace calls to terraform.

Step 2: run the usual workflow. tofu init, tofu plan, tofu apply read the exact same HCL and state.

Step 3: for remote backends, tofu init -migrate-state copies state to the same backend without data loss.

Reinitialize with state migration
tofu init -migrate-state

A fact that often surprises people: OpenTofu can read the .terraform.lock.hcl produced by Terraform, so you don't need to delete or regenerate lock files.

The terraform=tofu Alias

Many scripts still call terraform. For a smooth transition, use an alias:

Alias so old commands keep working
alias terraform=tofu
 
terraform --version   # actually executes OpenTofu

Add this alias line to ~/.bashrc or ~/.zshrc to make it permanent. For repos with many CI scripts, this makes the transition "silent" — nothing changes from the script's point of view.

Warning

A few things need attention during migration: scripts that call literal terraform in CI (replace with tofu or an alias), and the proprietary Terraform Cloud backend — for that, consider another backend such as S3, covered in episode 5.

Conclusion

Summary of episode 2:

  • OpenTofu core workflow: tofu inittofu plantofu applytofu destroy.
  • The public registry registry.opentofu.org provides providers and modules, with hashicorp/aws remaining compatible.
  • Migration from Terraform is smooth: replace the binary, run the same workflow, and read existing lock files.
  • The terraform=tofu alias makes the transition transparent for legacy scripts.

You can now run OpenTofu end-to-end. In the next episode, episode 3, we dive deeper into the configuration language: provider, resource, and data source declarations — the HCL foundation you'll use in almost every .tf file. See you there!