Deploying Infrastructure With OpenTofu
This tutorial explains how to deploy infrastructure with OpenTofu, from installing the CLI to provisioning and destroying a real cloud resource.
Join the DZone community and get the full member experience.
Join For FreeOpenTofu is an open-source infrastructure as code (IaC) tool maintained by the Linux Foundation. It lets you define cloud infrastructure in configuration files and deploy it with a single command-line tool called tofu. This tutorial explains how to deploy infrastructure with OpenTofu, from installing the CLI to provisioning and destroying a real cloud resource.
What You Need Before You Start
You need three things to follow along:
- An AWS account with credentials configured locally (the AWS command-line interface reads them from
~/.aws/credentialsor standard environment variables). - Basic comfort in a terminal.
- About 15 minutes.
The resources in this tutorial cost almost nothing, and the final step deletes everything you create. Pick a region you are happy to work in, such as us-east-1.
A Quick Word on OpenTofu
OpenTofu is a fork of Terraform, created in 2023 after Terraform moved to the Business Source License (BSL), a source-available license that is not OSI-approved open source. OpenTofu is a Linux Foundation project and was accepted into the Cloud Native Computing Foundation (CNCF) as a sandbox project in 2025.
The configuration language is the same HashiCorp Configuration Language (HCL) you may already know, every provider works the same way, and the command-line interface is tofu instead of terraform. If you have written Terraform before, you already know most of this.
Step 1: Install OpenTofu
Install OpenTofu using whichever method works best for your machine.
On macOS or Linux with Homebrew:
brew install opentofu
On Linux or macOS without Homebrew, use the official installer script:
curl --proto '=https' --tlsv1.2 -fsSL https://get.opentofu.org/install-opentofu.sh -o install-opentofu.sh
chmod +x install-opentofu.sh
./install-opentofu.sh --install-method standalone
rm install-opentofu.sh
The standalone installer verifies the integrity of what it downloads, so it expects cosign or GnuPG to be available. If you don't have either and just want to try it quickly, add --skip-verify to the install command.
On Windows, use winget:
winget install --exact --id=OpenTofu.Tofu
Confirm the install worked:
tofu --version
You should see OpenTofu v1.12.0 or later.
Step 2: Write Your First Configuration
Create a new directory and a single file inside it called main.tf:
mkdir tofu-demo && cd tofu-demo
Open main.tf and add the following. Each block is explained right after.
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 6.0"
}
random = {
source = "hashicorp/random"
version = "~> 3.0"
}
}
}
provider "aws" {
region = "us-east-1"
}
resource "random_pet" "suffix" {
length = 2
}
resource "aws_s3_bucket" "demo" {
bucket = "tofu-demo-${random_pet.suffix.id}"
}
output "bucket_name" {
value = aws_s3_bucket.demo.bucket
}
A few things worth understanding here. The terraform block declares which providers your configuration depends on and where to download them. OpenTofu keeps this block name for backward compatibility, so the same configuration runs on either tool.
The provider "aws" block sets the region you deploy into. The random_pet resource generates a short, readable suffix such as clever-mongoose, which keeps your bucket name globally unique without you having to invent one. The aws_s3_bucket resource is the infrastructure you are actually creating, and it references the random suffix, so OpenTofu knows to create the suffix first.
The output block prints the final bucket name once everything is deployed.
Step 3: Initialize the Project
Run tofu init from inside your project directory:
tofu init
This reads your terraform block, downloads the AWS and random providers from the OpenTofu registry, and sets up the working directory. You only rerun it when you add a new provider or module. You should see a message confirming OpenTofu has been initialized.
Step 4: Preview the Changes
Before OpenTofu touches your account, ask it what it intends to do:
tofu plan
The plan is the most important habit in IaC. It shows you exactly what will be created, changed, or destroyed before anything happens. For this configuration, the plan shows two resources to add: the random pet and the S3 bucket. Read it. Make sure it matches what you expect.
A clean plan-and-review step is what stops a one-line config change from accidentally deleting a database.
Step 5: Deploy
When the plan looks right, apply it:
tofu apply
OpenTofu shows you the plan one more time and waits for you to type yes. Confirm, and it provisions the bucket. When it finishes, you see your bucket_name output. Open the S3 console in AWS and your new bucket is there, created entirely from code.
You now have real infrastructure under version control. Change the configuration, run tofu plan to see the diff, and tofu apply to roll it out. That loop, edit, then plan, then apply, is the whole job.
Step 6: Understand State
After your first apply, OpenTofu creates a file called terraform.tfstate in your directory. This is the state file, which OpenTofu uses to map the resources in your configuration to the actual resources in your account. When you run a plan, OpenTofu compares your configuration, the state file, and the actual infrastructure to work out what changed.
On your laptop, with one person and one project, a local state file is fine. It stops being fine the moment a second engineer needs to run a deployment. Two people with two copies of the state file will overwrite each other's work.
The state file also holds resource metadata you do not want sitting in a Git repository or on a shared drive. This is the problem every team hits once IaC moves beyond a single person.
Step 7: Clean Up
Tear down everything you created so it costs you nothing:
tofu destroy
OpenTofu shows you what it will delete and waits for a yes. Confirm, and your bucket and the random suffix are gone. The destroy command is the counterpart to apply, and it reads the same state file to know what to remove.
Where This Goes Next
Running tofu from your laptop is the right way to learn. It is the wrong way to run infrastructure for a team. Once more than one engineer is involved, you need shared remote state with locking so two applies cannot collide, a record of who changed what and when, policy checks that run before an apply rather than after an incident, and a way to catch drift when someone makes a manual change in the console.
You can assemble these pieces yourself with a remote state backend, a continuous integration pipeline, and a set of scripts. Many teams start there.
As the number of stacks and engineers grows, that homegrown setup becomes its own maintenance burden, which is the point where teams adopt an infrastructure orchestration platform.
A platform like Spacelift manages OpenTofu runs against shared remote state, gates changes with policy as code, and detects drift between your configuration and what is actually deployed, with an audit trail across every change. It is one option in a category of tooling built to solve the team-scale problems this tutorial only hints at. The decision of whether and when to adopt one depends on how many people and environments you are managing.
For now, you have the foundation: install, write, init, plan, apply, and destroy. Every OpenTofu project, from a single bucket to a fleet of production environments, runs on the same loop you just learned.
Next, read the OpenTofu documentation on modules and remote backends to see how that loop scales from one file to a real codebase.
Opinions expressed by DZone contributors are their own.
Comments