OpenTofu Migration
SkillCloud & infraMigrate from Terraform to OpenTofu with state compatibility, provider registry setup, and CI/CD pipeline updates. Use when adopting the open-source Terraform fork or evaluating license-free IaC.
Available today. Use it from your connected AI after setup.
No other account needed.
Connect ahel once, and every AI you use reads what you have installed.
Then ask your AI: use the OpenTofu Migration skill
What this skill tells your AI
The instructions your AI receives, as published by bagelhole/devops-security-agent-skills in infrastructure/iac/opentofu-migration/SKILL.md and read by ahel’s review.
Migrate infrastructure-as-code from HashiCorp Terraform to the open-source OpenTofu fork.
When to Use This Skill
Use this skill when:
- Migrating from Terraform to OpenTofu for licensing reasons
- Setting up a new IaC project and evaluating OpenTofu vs Terraform
- Updating CI/CD pipelines to use OpenTofu
- Configuring the OpenTofu provider registry
Prerequisites
- Existing Terraform codebase (0.13+)
- OpenTofu CLI installed
- State backend access (S3, GCS, Azure Blob, etc.)
Install OpenTofu
# macOS
brew install opentofu
# Linux (Debian/Ubuntu)
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 deb
rm install-opentofu.sh
# Linux (RPM)
./install-opentofu.sh --install-method rpm
# Docker
docker run --rm -v $(pwd):/workspace -w /workspace \
ghcr.io/opentofu/opentofu:latest init
# Verify installation
tofu --version
Migration Checklist
1. Verify Compatibility
# OpenTofu reads Terraform state files directly — no migration needed
# Check your Terraform version (must be <= 1.6.x for full compat)
terraform version
# Run plan with OpenTofu against existing state
tofu init
tofu plan
2. Replace CLI Commands
| Terraform | OpenTofu |
|---|---|
terraform init | tofu init |
terraform plan | tofu plan |
terraform apply | tofu apply |
terraform destroy | tofu destroy |
terraform fmt | tofu fmt |
terraform validate | tofu validate |
terraform state | tofu state |
terraform import | tofu import |
3. Update Provider Lock File
# Remove Terraform lock and regenerate for OpenTofu
rm .terraform.lock.hcl
tofu init -upgrade
# Verify providers resolve correctly
tofu providers
4. Update State Backend
State files are compatible — no migration needed. Just verify:
# backend.tf — works identically with OpenTofu
terraform {
backend "s3" {
bucket = "mycompany-tfstate"
key = "prod/infrastructure.tfstate"
region = "us-east-1"
dynamodb_table = "terraform-locks"
encrypt = true
}
}
# Verify state access
tofu init
tofu state list
5. Provider Registry
OpenTofu uses its own registry but mirrors most Terraform providers:
# versions.tf
terraform {
required_version = ">= 1.6.0"
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
kubernetes = {
source = "hashicorp/kubernetes"
version = "~> 2.25"
}
# OpenTofu-specific providers
random = {
source = "hashicorp/random"
version = "~> 3.6"
}
}
}
OpenTofu-Specific Features
State Encryption (Not in Terraform)
# OpenTofu supports native state encryption
terraform {
encryption {
key_provider "pbkdf2" "my_key" {
passphrase = var.state_passphrase
}
method "aes_gcm" "encrypt" {
keys = key_provider.pbkdf2.my_key
}
state {
method = method.aes_gcm.encrypt
enforced = true
}
plan {
method = method.aes_gcm.encrypt
enforced = true
}
}
}
Early Variable/Local Evaluation
# OpenTofu allows variables in backend config and module sources
terraform {
backend "s3" {
bucket = var.state_bucket # Works in OpenTofu, not Terraform
key = "${var.project}/terraform.tfstate"
region = var.aws_region
}
}
CI/CD Pipeline Updates
GitHub Actions
# .github/workflows/tofu.yml
name: OpenTofu
on:
pull_request:
paths: ["infra/**"]
push:
branches: [main]
paths: ["infra/**"]
permissions:
id-token: write
contents: read
pull-requests: write
jobs:
plan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup OpenTofu
uses: opentofu/setup-opentofu@v1
with:
tofu_version: "1.8.0"
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: arn:aws:iam::123456789:role/tofu-deploy
aws-region: us-east-1
- name: Init
run: tofu init
working-directory: infra/
- name: Plan
id: plan
run: tofu plan -no-color -out=tfplan
working-directory: infra/
- name: Comment PR with plan
if: github.event_name == 'pull_request'
uses: actions/github-script@v7
with:
script: |
const output = `#### OpenTofu Plan
\`\`\`
${{ steps.plan.outputs.stdout }}
\`\`\``;
github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: output.substring(0, 65536)
});
apply:
needs: plan
if: github.ref == 'refs/heads/main'
runs-on: ubuntu-latest
environment: production
steps:
- uses: actions/checkout@v4
- uses: opentofu/setup-opentofu@v1
- uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: arn:aws:iam::123456789:role/tofu-deploy
aws-region: us-east-1
- run: tofu init && tofu apply -auto-approve
working-directory: infra/
GitLab CI
# .gitlab-ci.yml
stages: [validate, plan, apply]
variables:
TOFU_VERSION: "1.8.0"
.tofu-base:
image: ghcr.io/opentofu/opentofu:${TOFU_VERSION}
before_script:
- tofu init
validate:
extends: .tofu-base
stage: validate
script:
- tofu fmt -check
- tofu validate
plan:
extends: .tofu-base
stage: plan
script:
- tofu plan -out=tfplan
artifacts:
paths: [tfplan]
apply:
extends: .tofu-base
stage: apply
script:
- tofu apply tfplan
when: manual
only: [main]
dependencies: [plan]
Coexistence Strategy
If you need both tools during migration:
# Use aliases to avoid conflicts
alias tf="terraform"
alias tofu="tofu"
# Or use direnv per-project
# .envrc
export PATH="/opt/opentofu/bin:$PATH"
# Wrapper script for gradual migration
#!/bin/bash
if [ -f ".use-opentofu" ]; then
exec tofu "$@"
else
exec terraform "$@"
fi
Troubleshooting
| Issue | Solution |
|---|---|
| Provider not found | Run tofu init -upgrade, check registry.opentofu.org |
| State lock conflict | Same as Terraform — check DynamoDB/blob lease |
| Version constraint error | Update required_version to >= 1.6.0 |
| Backend migration | State is compatible — just run tofu init |
| Missing provider credentials | Same env vars work (AWS_*, GOOGLE_*, ARM_*) |
Related Skills
- terraform-aws — AWS IaC patterns (works with both)
- terraform-azure — Azure IaC patterns
- terraform-gcp — GCP IaC patterns
- policy-as-code — OPA policy checks for IaC
Signals
- GitHub stars
- 1k
- Forks
- 157
- Last commit
- May 2026
Advanced
- Catalog kind
- skill
- Gateway key
opentofu-migration- Source
- github.com/bagelhole/devops-security-agent-skills