饮墨

子安饮墨馀三斗,留与卿儿作赋来

OpenTofu 替代 Terraform:生产环境迁移实战指南

痛点

2023 年 HashiCorp 将 Terraform 许可证从 MPL 2.0 切换为 BSL 1.1,对商业用途施加限制。对于中大型团队,这意味着:

  • 合规风险:如果你的产品或服务与 HashiCorp 构成竞争关系,继续使用 Terraform 可能违反许可证
  • 供应商锁定:BSL 限制了社区分发和二次开发的自由度
  • 长期成本不确定性:未来可能进一步收紧许可或推商业版

OpenTofu 是 Linux Foundation 托管的 Terraform 开源分支(fork),保持 MPL 2.0 许可,API 兼容 Terraform 1.6+,并持续迭代新特性(如 state encryption、provider-defined functions)。如果你的团队正在评估迁移,这篇文章给出一套经过生产验证的迁移方案。

方案概览

┌──────────────────────────────────────────────┐
│        迁移路径(零停机,渐进式)              │
├──────────────────────────────────────────────┤
│ 1. 环境评估 → 2. 安装 OpenTofu               │
│ 3. State 兼容性验证 → 4. CI/CD 管道切换       │
│ 5. 灰度推广 → 6. 全量替换                    │
└──────────────────────────────────────────────┘

核心原则:OpenTofu 与 Terraform 1.6.x state 文件完全兼容,迁移本质上是替换二进制,而非重写代码。

实操步骤

Step 1:安装 OpenTofu

# Linux (amd64) — 推荐用官方安装脚本
curl -fsSL https://get.opentofu.org/install-opentofu.sh | sh -s -- --install-method standalone

# 验证版本
tofu --version
# OpenTofu v1.8.x

也可通过 brew install opentofu(macOS)或容器镜像 ghcr.io/opentofu/opentofu:latest 使用。

Step 2:现有项目兼容性检查

cd /path/to/your-terraform-project

# 直接用 tofu 执行 init(使用已有 .terraform.lock.hcl)
tofu init

# 生成 plan,对比 terraform plan 的输出
tofu plan -out=tofu.tfplan

# 关键:确认 plan 中无差异(No changes)
# 如果资源数量与 terraform plan 一致,说明完全兼容

注意事项: - 如果使用了 terraform block 中的 required_version 约束,需改为兼容 OpenTofu 的写法:

terraform {
  # 兼容写法:同时适配 Terraform 和 OpenTofu
  required_version = ">= 1.6.0"

  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 5.0"
    }
  }
}
  • OpenTofu 沿用 Terraform Registry 的 provider,无需更换 provider source

Step 3:State 文件验证与备份

# 备份当前 state(无论用本地还是远端 backend)
tofu state pull > state_backup_$(date +%Y%m%d).json

# 验证 state 中的资源数量
tofu state list | wc -l

# 对比 terraform state list 的输出
diff <(terraform state list | sort) <(tofu state list | sort)
# 预期输出为空(无差异)

对于使用 S3 + DynamoDB 作为远端 backend 的团队,OpenTofu 完全兼容,无需任何 backend 配置修改:

terraform {
  backend "s3" {
    bucket         = "my-terraform-state"
    key            = "prod/infra.tfstate"
    region         = "us-east-1"
    dynamodb_table = "terraform-locks"
    encrypt        = true
  }
}

Step 4:CI/CD 管道切换

以 GitHub Actions 为例,替换 hashicorp/setup-terraformopentofu/setup-opentofu

# .github/workflows/infra.yml
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: Init
        run: tofu init -no-color

      - name: Plan
        run: tofu plan -no-color -out=plan.tfplan

      - name: Apply (main branch only)
        if: github.ref == 'refs/heads/main'
        run: tofu apply -no-color -auto-approve plan.tfplan

对于 GitLab CI,将 image: hashicorp/terraform:latest 改为 image: ghcr.io/opentofu/opentofu:latest,命令从 terraform 改为 tofu

Step 5:利用 OpenTofu 独有特性

迁移完成后,可以启用 OpenTofu 的差异化功能:

State Encryption(生产强烈推荐):

terraform {
  encryption {
    key_provider "pbkdf2" "main" {
      passphrase = var.state_encryption_passphrase
    }

    method "aes_gcm" "default" {
      keys = key_provider.pbkdf2.main
    }

    state {
      method = method.aes_gcm.default
    }

    plan {
      method = method.aes_gcm.default
    }
  }
}

这解决了 Terraform 长期被诟病的 state 文件明文存储敏感信息 问题。即使 S3 bucket 泄露,攻击者也无法读取 state 中的密码、密钥等。

避坑指南

1. Provider 版本锁定问题

现象tofu init 报错 provider not found in registry

原因:某些企业私有 Registry 的 provider 签名验证机制不兼容

解决

# 临时跳过签名验证(仅用于迁移验证,生产环境应修复 Registry 配置)
tofu init -upgrade -verify-plugins=false

2. Wrapper 脚本兼容

现象:团队内部封装的 Makefile 或脚本硬编码了 terraform 命令

解决:设置 alias 做平滑过渡

# /etc/profile.d/tofu.sh — 全局 alias
alias terraform='tofu'

# 或在 Makefile 中使用变量
TF_BIN ?= tofu
plan:
    $(TF_BIN) plan

3. Terraform Cloud/Enterprise 用户

现象:使用 cloud {} block 作为 backend 的项目无法直接迁移

解决:OpenTofu 不支持 Terraform Cloud backend,需先将 state 迁移到 S3/GCS/Consul 等开放 backend:

# 先从 Terraform Cloud 拉取 state
terraform state pull > local.tfstate

# 修改 backend 配置为 S3
# 然后用 OpenTofu 初始化并推送
tofu init -migrate-state

总结

维度 Terraform OpenTofu
许可证 BSL 1.1(限制商业) MPL 2.0(完全开源)
State 加密 ❌ 不支持 ✅ 内置 AES-GCM
Provider 兼容 100% 兼容
社区治理 HashiCorp 主导 Linux Foundation 托管
迁移成本 极低(替换二进制)

核心结论:OpenTofu 迁移的技术门槛极低(本质是 s/terraform/tofu/g),真正的挑战在于团队流程切换和 CI/CD 管道更新。建议采用灰度策略——先在非生产环境验证,再逐步推广到生产 module。如果你还在用 Terraform Cloud,需额外规划 backend 迁移,这是唯一有实质工作量的环节。

您还没有登录,请登录后发表评论。