OpenTofu Migration Guide: Moving 200+ Terraform Modules Without Downtime

HashiCorp's BSL licensing change forced a reckoning across the infrastructure-as-code community. OpenTofu — the Linux Foundation-backed fork — emerged as the open-source alternative. But how do you actually migrate a production Terraform estate without breaking everything?

Y
Yash Pritwani
4 min read read

# OpenTofu Migration Guide: Moving 200+ Terraform Modules Without Downtime

HashiCorp's BSL licensing change forced a reckoning across the infrastructure-as-code community. OpenTofu — the Linux Foundation-backed fork — emerged as the open-source alternative. But how do you actually migrate a production Terraform estate without breaking everything?

We've done this migration for three clients now, totaling 200+ modules across multiple AWS accounts. Here's the complete playbook.

Why Migrate Now?

The technical argument is simple: OpenTofu maintains full compatibility with Terraform's HCL syntax and state format. The strategic argument is stronger: your infrastructure tooling shouldn't be subject to unilateral licensing changes by a single vendor.

OpenTofu 1.8+ introduced client-side state encryption — a feature Terraform doesn't offer. The fork is diverging in useful ways.

Pre-Migration Audit

Step 1: Provider Inventory

Not all providers require changes. Run this audit:

# List all providers in use
grep -r "required_providers" --include="*.tf" -l | \
  xargs grep "source" | sort -u

Most providers (AWS, GCP, Azure, Cloudflare) work identically. Watch for:

hashicorp/consul and hashicorp/vault — these still work but check version compatibility
Any internal/custom providers — these need testing

Step 2: Binary Reference Scan

# Find every reference to 'terraform' binary
grep -rn "terraform " scripts/ .github/ .gitlab-ci.yml Makefile \
  --include="*.sh" --include="*.yml" --include="*.yaml" --include="Makefile"

We typically find 30-50 references across CI/CD configs, wrapper scripts, Makefiles, and documentation.

Step 3: State File Compatibility Test

OpenTofu reads Terraform state files natively. Verify:

tofu init
tofu state list    # Should match terraform state list exactly
tofu state show aws_instance.web  # Spot-check a few resources

Migration Execution

Phase 1: Install OpenTofu

# Linux (snap)
snap install --classic opentofu

# macOS (brew)
brew install opentofu

# Docker
docker pull ghcr.io/opentofu/opentofu:latest

Phase 2: CI/CD Pipeline Updates

GitHub Actions:

- uses: opentofu/setup-opentofu@v1
  with:
    tofu_version: "1.8.0"
- run: tofu init
- run: tofu plan -out=plan.tfplan

GitLab CI:

image: ghcr.io/opentofu/opentofu:1.8
script:
  - tofu init -backend-config="..."
  - tofu plan

Atlantis: Update repos.yaml to use tofu binary. Atlantis supports OpenTofu natively since v0.28.

Phase 3: Lock File Migration

# Remove old lock file
rm .terraform.lock.hcl

# Regenerate with OpenTofu
tofu init -upgrade

The new lock file (.terraform.lock.hcl — same name) will reference the same provider versions.

Phase 4: Staged Rollout

1. Week 1: Migrate non-critical modules (dev/staging) 2. Week 2: Run tofu plan against production — compare output with last terraform plan 3. Week 3: Switch production pipelines 4. Week 4: Remove Terraform binary, update documentation

Post-Migration: Leveraging OpenTofu-Only Features

Client-Side State Encryption

terraform {
  encryption {
    method "aes_gcm" "default" {
      keys = key_provider.aws_kms.default
    }
    state {
      method = method.aes_gcm.default
    }
  }
}

This encrypts state at rest — before it reaches your backend. Terraform doesn't offer this.

Common Pitfalls

1. Wrapper scripts with version checks — Scripts that run terraform version and parse output will break. Grep for version-parsing logic in your automation. 2. Terragrunt compatibility — Terragrunt supports OpenTofu since v0.54. If you're on an older version, update Terragrunt first, then migrate the binary. 3. IDE plugins — VS Code's Terraform extension works with OpenTofu out of the box. JetBrains users need the separate OpenTofu plugin from the marketplace. 4. Documentation drift — Search-replace "terraform" with "tofu" in all runbooks, READMEs, and onboarding docs. This is easy to forget and causes confusion for new team members. 5. Terraform Cloud/Enterprise dependencies — If you're using Terraform Cloud for remote state or runs, you'll need an alternative. OpenTofu works with any S3/GCS/Azure Blob backend, plus Spacelift and env0 support OpenTofu natively.

Testing Strategy

Don't just run tofu plan and call it done. Build a proper validation matrix:

#!/bin/bash
# migration-test.sh — run against each module

set -euo pipefail

MODULE_DIR=$1

cd "$MODULE_DIR"

# 1. Init
tofu init -upgrade 2>&1 | tee /tmp/tofu-init.log

# 2. Validate
tofu validate

# 3. Plan (compare with last terraform plan)
tofu plan -out=tofu.plan -no-color > /tmp/tofu-plan.txt

# 4. State operations
tofu state list > /tmp/tofu-state.txt

# 5. Compare resource counts
TF_COUNT=$(wc -l < /tmp/tf-state.txt 2>/dev/null || echo 0)
TOFU_COUNT=$(wc -l < /tmp/tofu-state.txt)

if [ "$TF_COUNT" != "$TOFU_COUNT" ]; then
  echo "WARNING: Resource count mismatch! TF=$TF_COUNT TOFU=$TOFU_COUNT"
  exit 1
fi

echo "Module $MODULE_DIR: PASS"

Run this against every module in staging before touching production. We scripted this and ran it across all 200+ modules in under an hour.

Results

For our largest migration (200+ modules, 3 AWS accounts):

Total effort: 14 hours over a weekend
Downtime: Zero
State corruption: None
Post-migration issues: 2 (both wrapper script path issues, fixed in <10 minutes)
6-month post-migration status: Zero OpenTofu-specific bugs. Two features we gained that Terraform doesn't have (state encryption, early variable evaluation).

The migration is far less scary than it looks. The state compatibility is rock-solid. The only real work is updating your CI/CD pipelines and wrapper scripts — the infrastructure itself doesn't change at all.

Should You Wait?

No. Here's why:

OpenTofu has feature parity with Terraform 1.6 and is diverging with useful additions
The Linux Foundation backing means it won't face the same licensing risk
Every month you wait, more CI/CD pipeline drift makes migration harder
Your competitors are already migrating — the OpenTofu registry has seen 400% growth in the last 6 months

The best time to migrate was when BSL was announced. The second best time is this weekend.

---

Need help migrating your Terraform estate to OpenTofu? We've done this at scale. Book a free consultationBook a free consultationhttps://techsaas.cloud/contact or explore our DevOps servicesDevOps serviceshttps://techsaas.cloud/services.

#[OpenTofu#Terraform#IaC#Migration#DevOps#Open Source]

Need help with general?

TechSaaS provides expert consulting and managed services for cloud infrastructure, DevOps, and AI/ML operations.