Skip to the content.

OpenTofu

Information

Introduction

OpenTofu is an open-source infrastructure as code (IaC) tool for provisioning and managing cloud, network, platform, and Kubernetes resources.

It is a community-driven fork of Terraform and is designed to remain compatible with many existing Terraform workflows, providers, modules, and HCL configurations.

In practice, OpenTofu is used in a very similar way to Terraform: define infrastructure declaratively, create a plan, review the changes, and apply them to the target environment.

Key Features

Installation

Windows

Install OpenTofu from the official instructions or package manager for your environment.

Linux

Install OpenTofu from the official package repository or by downloading a release from the project site.

For current installation instructions, see the official documentation:

What is it for?

Typical OpenTofu use cases include:

Step-by-Step Usage Pattern

The normal OpenTofu workflow is close to Terraform:

  1. Define providers and resources in HCL.
  2. Run tofu init to download providers and initialize the working directory.
  3. Run tofu plan to review what will change.
  4. Run tofu apply to create or update the infrastructure.
  5. Run tofu destroy when you want to tear down temporary environments.

Typical commands:

tofu init
tofu plan
tofu apply

Quick Start: What You Actually Need to Do

The current page describes what OpenTofu can manage, but in practice most people first want a minimal path to getting something real up and running.

The shortest practical path is usually:

  1. choose one provider such as Hetzner, AWS, Google Cloud, or Azure
  2. create provider credentials in that platform
  3. install OpenTofu
  4. create a small project directory with main.tf
  5. define one provider and one or two resources
  6. run tofu init
  7. run tofu plan
  8. run tofu apply
  9. verify the created server, network, firewall, or cluster in the provider console

In other words, OpenTofu itself does not create infrastructure magically. You still need:

For most teams, the best first exercise is not a full Kubernetes platform. Start with one of these:

Minimal Project Structure

A very small OpenTofu project often starts like this:

my-infra/
  main.tf
  variables.tf
  outputs.tf
  terraform.tfvars

For a first experiment, even just main.tf is enough.

Minimal Example Workflow

Create a new directory, add a main.tf, and then run the standard workflow:

tofu init
tofu plan
tofu apply

After the resources exist, later changes usually follow the same pattern:

tofu plan
tofu apply

And when the environment is no longer needed:

tofu destroy

Concrete Starter Examples

The examples below are intentionally small. They are not full production environments, but they show what you should actually write to get started.

Example 1. Simple Hetzner VPS

This is a good first example because it is small, practical, and easy to understand.

Before using it, you typically need:

Example main.tf:

terraform {
  required_providers {
    hcloud = {
      source = "hetznercloud/hcloud"
    }
  }
}

provider "hcloud" {
  token = var.hcloud_token
}

variable "hcloud_token" {
  type      = string
  sensitive = true
}

resource "hcloud_server" "web1" {
  name        = "web1"
  image       = "ubuntu-24.04"
  server_type = "cx22"
  location    = "nbg1"
  ssh_keys    = ["default"]
}

output "web1_ipv4" {
  value = hcloud_server.web1.ipv4_address
}

Typical flow:

  1. create terraform.tfvars with hcloud_token = "..."
  2. run tofu init
  3. run tofu plan
  4. run tofu apply
  5. connect with ssh to the created server IP from the output

This is the fastest way to understand the provider -> resource -> plan -> apply model.

Example 2. AWS Security Group for a Small Web Server

This example is useful when you first want to understand networking and firewall logic rather than a whole platform.

terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 5.0"
    }
  }
}

provider "aws" {
  region = "eu-central-1"
}

resource "aws_security_group" "web_sg" {
  name        = "web-sg"
  description = "Allow web and SSH access"

  ingress {
    from_port   = 22
    to_port     = 22
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }

  ingress {
    from_port   = 80
    to_port     = 80
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }

  ingress {
    from_port   = 443
    to_port     = 443
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }

  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }
}

This does not yet create a full instance, but it gives a concrete first step for understanding repeatable access rules.

In real environments, you would usually attach this security group to EC2, a load balancer, or other networked resources.

Example 3. Small AWS VPC Skeleton

If your first goal is network setup, a tiny VPC skeleton is often more useful than jumping directly into EKS.

terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 5.0"
    }
  }
}

provider "aws" {
  region = "eu-central-1"
}

resource "aws_vpc" "main" {
  cidr_block = "10.10.0.0/16"

  tags = {
    Name = "main-vpc"
  }
}

resource "aws_subnet" "public_a" {
  vpc_id            = aws_vpc.main.id
  cidr_block        = "10.10.1.0/24"
  availability_zone = "eu-central-1a"

  tags = {
    Name = "public-a"
  }
}

This gives you a simple base that can later be extended with:

How to Move from Example to Real Setup

Once a minimal example works, the next practical step is usually:

  1. move credentials out of hard-coded files into environment variables or secure secret handling
  2. split configuration into main.tf, variables.tf, and outputs.tf
  3. add separate values for dev, test, and prod
  4. introduce remote state storage and state locking when working in a team
  5. convert repeated resource groups into reusable modules

For example, a realistic growth path is:

Practical Tips for Getting Up and Running Faster

If the goal is to get something working quickly, these tips help:

Common First Real-World Setups

Typical first useful projects with OpenTofu are:

These are generally much better first targets than trying to automate everything in one go.

How to Set Up Different Things with OpenTofu

OpenTofu is suitable for many kinds of infrastructure provisioning. Common examples include:

1. VPS and Virtual Machines

Typical targets:

Typical resources managed around a VPS:

This makes OpenTofu useful for small single-server setups as well as larger multi-node environments.

2. Kubernetes Clusters

Typical targets:

Typical resources around Kubernetes:

OpenTofu is often used to provision the base cluster and surrounding cloud infrastructure, while cluster workloads are deployed later with Helm, kubectl, Argo CD, or similar tools.

3. Networks

Typical network-related setups include:

This is one of the strongest IaC use cases because network design is easier to review in code than by clicking in cloud consoles.

4. Firewalls and Access Rules

Typical security-related setups include:

This is especially useful when you need repeatable policies across dev, test, and prod environments.

Example Provider Scenarios

Below are typical ways OpenTofu is used across major providers.

AWS

Common AWS targets with OpenTofu:

Typical scenario:

Google Cloud

Common Google Cloud targets with OpenTofu:

Typical scenario:

Azure

Common Azure targets with OpenTofu:

Typical scenario:

Other Providers

OpenTofu is also practical for:

This makes it a good choice when the same team needs one IaC workflow across public cloud, private cloud, and hybrid infrastructure.

Practical Infrastructure Patterns

VPS + Firewall + DNS

A common starter pattern is:

  1. provision one or more virtual machines
  2. attach SSH keys
  3. open only required firewall ports such as 22, 80, and 443
  4. allocate a public IP
  5. create DNS records pointing to the host

This works well for simple web applications, reverse proxies, and smaller backend services.

Kubernetes + Ingress + IP Restrictions

Another common pattern is:

  1. provision a managed Kubernetes cluster
  2. create networking and node pools
  3. install an ingress controller or cloud-native load balancer integration
  4. restrict access with cloud firewall rules, security groups, or provider-specific policies
  5. point DNS records to the ingress or load balancer

This is useful for APIs, web applications, and internal platforms.

Reusable Modules per Environment

Teams often create reusable modules for:

Then they apply the same modules to dev, test, and prod with different variables.

Relationship to Terraform

If you already know Terraform, the transition to OpenTofu is usually straightforward because:

This makes terraform.md directly useful as conceptual background also when working with OpenTofu.

Similar Software

See also