关于 opentofu-guide
面向 Terraform 用户和基础设施团队的 OpenTofu 知识与迁移指南,介绍兼容性、差异和迁移步骤。内容还涵盖状态加密、循环导入及变量求值等 OpenTofu 功能。
主要功能
- 01Terraform 与 OpenTofu 差异
- 02迁移兼容性评估步骤
- 03状态加密配置说明
- 04循环导入块示例
- 05变量与模块源求值
适用场景
- 01评估从 Terraform 切换的可行性
- 02迁移项目配置与状态
- 03为状态文件启用加密
- 04在配置中批量导入资源
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ josiahsiegel/ claude-plugin-marketplace --skill opentofu-guide安装后在 Claude Code 中输入/opentofu-guide确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/opentofu-1.10-features.mdopentofu-1.11-features.mdstate-encryption.md详细介绍
🚨 关键指南
Windows 文件路径要求
强制要求:在 Windows 上始终使用反斜杠表示文件路径
在 Windows 上使用 Edit 或 Write 工具时,必须在文件路径中使用反斜杠(\),而不是正斜杠(/)。
示例:
- ❌ 错误:
D:/repos/project/file.tsx - ✅ 正确:
D:\repos\project\file.tsx
此要求适用于:
- Edit 工具的 file_path 参数
- Write 工具的 file_path 参数
- Windows 系统上的所有文件操作
文档编写指南
除非用户明确要求,否则切勿创建新的文档文件。
- 优先事项:更新现有的 README.md 文件,而不是创建新的文档
- 保持仓库整洁:保持仓库根目录整洁——除非用户另有要求,否则只保留 README.md
- 风格:文档应简洁、直接、专业,避免使用 AI 生成式语气
- 用户偏好:只有用户明确要求提供文档时,才创建额外的 .md 文件
OpenTofu 专业知识与迁移指南
概述
OpenTofu 是 Terraform 的开源分支,诞生于 2023 年,此前 HashiCorp 将 Terraform 的许可证从 MPL 2.0 更改为 BSL(Business Source License)。OpenTofu 由 Linux Foundation 管理,与 Terraform 1.5.x 完全兼容,同时加入了由社区推动的功能。
主要区别(2025 年)
许可证
Terraform(HashiCorp):
- 自 2023 年 8 月起采用 BSL(Business Source License)
- 限制将其用于与之竞争的产品的商业用途
- IBM 于 2024 年收购了 HashiCorp
OpenTofu:
- MPL 2.0(Mozilla Public License)
- 真正开源
- 由 Linux Foundation 治理
- 由社区推动开发
功能创新(2025 年)
OpenTofu 1.7 功能:
- 状态加密:客户端加密(社区提出此需求已有 5 年以上)
- 可循环导入块:在导入块中使用 for_each
- 动态 Provider 函数:支持由 Provider 定义的函数
- 提前评估变量:在 terraform 块中使用变量
OpenTofu 1.8 功能(最新):
- OpenTofu 专属覆盖项:平衡兼容性与创新
- 扩展提前评估变量的能力:在模块源中使用变量/locals
- 增强的 Provider 支持:改进 Provider SDK
Terraform 的优势:
- HCP Terraform:提供 Stacks、HYOK 和 Private VCS Access 的云平台
- 企业支持:HashiCorp/IBM 提供直接支持
- 更大的生态系统:更成熟的市场
- Sentinel 策略:策略即代码框架(350 多项 NIST 策略)
兼容性
100% 兼容:
- HCL 语法(相同的语言)
- Provider 生态系统(可访问相同的注册表)
- 状态文件格式(Terraform 1.5.x)
- 模块结构
- CLI 命令
迁移路径:
- 可直接替换 Terraform 1.5.x
- 无需更改代码
- 状态文件可移植(需考虑加密问题)
何时选择 OpenTofu 或 Terraform
选择 OpenTofu 的情况:
-
有开源要求:
- 组织政策要求使用开源工具
- 希望避免供应商绑定
- 担心未来许可证发生变化
-
需要状态加密:
- 合规要求使用客户端加密
- 希望在不使用 HCP Terraform 的情况下实现加密
- 有多云加密需求
-
优化成本:
- 希望免费使用状态加密
- 不需要 HCP Terraform 的功能
- 工具预算受限
-
由社区推动:
- 希望影响发展路线图
- 更倾向于由 Linux Foundation 治理
- 重视社区贡献
在以下情况下选择 Terraform:
-
需要企业级功能:
- 需要 HCP Terraform Stacks
- 需要 HYOK(自持密钥)
- 需要私有 VCS 访问
- 需要 Sentinel 策略强制执行
-
企业级支持:
- 需要 HashiCorp/IBM 的直接支持
- 需要 SLA 保障
- 需要合规认证
-
高级功能:
- 临时值(1.10+)
- Terraform Query(1.14+)
- Actions 块(1.14+)
- 优先获得最新的提供商功能
-
成熟的生态系统:
- 已有 HCP Terraform 投资
- 需要紧密集成
- 需要成熟的工具
从 Terraform 迁移到 OpenTofu
步骤 1:评估兼容性
# Check Terraform version
terraform version
# Must be 1.5.x or compatible
# Check provider versions
terraform providers
# All providers compatible (same registry)
步骤 2:安装 OpenTofu
Windows:
# Chocolatey
choco install opentofu
# Scoop
scoop install opentofu
# Manual
# Download from https://github.com/opentofu/opentofu/releases
macOS:
# Homebrew
brew install opentofu
# Manual
curl -L https://github.com/opentofu/opentofu/releases/download/v1.8.0/tofu_1.8.0_darwin_amd64.tar.gz | tar xz
sudo mv tofu /usr/local/bin/
Linux:
# Snap
snap install opentofu --classic
# Debian/Ubuntu
curl -fsSL https://get.opentofu.org/install-opentofu.sh | sh
# Manual
wget https://github.com/opentofu/opentofu/releases/download/v1.8.0/tofu_1.8.0_linux_amd64.tar.gz
tar -xzf tofu_1.8.0_linux_amd64.tar.gz
sudo mv tofu /usr/local/bin/
步骤 3:测试兼容性
# Navigate to Terraform directory
cd /path/to/terraform/project
# Initialize with OpenTofu (non-destructive)
tofu init
# Validate configuration
tofu validate
# Generate plan (compare with Terraform plan)
tofu plan
步骤 4:迁移状态(可选)
如果未使用状态加密:
# State is compatible - no migration needed
# Just switch from 'terraform' to 'tofu' commands
# Verify state
tofu show
如果启用状态加密:
# Configure encryption in .tofu file
cat > .tofu <<EOF
encryption {
state {
method = "aes_gcm"
keys {
name = "my_key"
passphrase = env.TOFU_ENCRYPTION_KEY
}
}
plan {
method = "aes_gcm"
keys {
name = "my_key"
passphrase = env.TOFU_ENCRYPTION_KEY
}
}
}
EOF
# Set encryption key
export TOFU_ENCRYPTION_KEY="your-secure-passphrase"
# Migrate state (automatically encrypts)
tofu init -migrate-state
步骤 5:更新 CI/CD
GitHub Actions:
# Before (Terraform)
- uses: hashicorp/setup-terraform@v3
with:
terraform_version: 1.5.0
# After (OpenTofu)
- uses: opentofu/setup-opentofu@v1
with:
tofu_version: 1.8.0
# Or manual install
- name: Install OpenTofu
run: |
curl -fsSL https://get.opentofu.org/install-opentofu.sh | sh
tofu version
Azure DevOps:
# Before
- task: TerraformInstaller@0
inputs:
terraformVersion: '1.5.0'
# After
- task: Bash@3
displayName: 'Install OpenTofu'
inputs:
targetType: 'inline'
script: |
curl -fsSL https://get.opentofu.org/install-opentofu.sh | sh
tofu version
GitLab CI:
# Before
image: hashicorp/terraform:1.5.0
# After
image: ghcr.io/opentofu/opentofu:1.8.0
状态加密(OpenTofu 独有)
配置
基本加密:
# .tofu or terraform.tf
encryption {
state {
method = "aes_gcm"
keys {
name = "primary_key"
passphrase = env.TOFU_STATE_ENCRYPTION_KEY
}
}
}
密钥轮换:
encryption {
state {
method = "aes_gcm"
keys {
# New key
name = "key_v2"
passphrase = env.TOFU_KEY_V2
# Old key (for decryption)
fallback {
name = "key_v1"
passphrase = env.TOFU_KEY_V1
}
}
}
}
云 KMS 集成:
# AWS KMS
encryption {
state {
method = "aws_kms"
keys {
name = "aws_key"
kms_key_id = "arn:aws:kms:us-east-1:123456789012:key/12345678-1234-1234-1234-123456789012"
}
}
}
# Azure Key Vault
encryption {
state {
method = "azurerm_key_vault"
keys {
name = "azure_key"
key_vault_key_id = "https://myvault.vault.azure.net/keys/mykey/version"
}
}
}
# GCP KMS
encryption {
state {
method = "gcp_kms"
keys {
name = "gcp_key"
kms_crypto_key = "projects/PROJECT_ID/locations/LOCATION/keyRings/RING/cryptoKeys/KEY"
}
}
}
最佳实践
-
安全存储密钥:
# Never commit keys echo "TOFU_ENCRYPTION_KEY=xxx" >> .env echo ".env" >> .gitignore # Use CI/CD secrets # GitHub: Repository Settings → Secrets # Azure DevOps: Pipeline → Variables → Secret -
定期轮换密钥:
# Generate new key NEW_KEY=$(openssl rand -base64 32) # Add to fallback, update configs # Migrate state tofu init -migrate-state -
备份未加密的状态:
# Before enabling encryption terraform state pull > backup-unencrypted.tfstate # Enable encryption tofu init -migrate-state # Verify tofu state pull # Should be encrypted in backend
可循环的导入块(OpenTofu 1.7+)
Terraform 1.5+(单个导入):
import {
to = azurerm_resource_group.example
id = "/subscriptions/.../resourceGroups/my-rg"
}
OpenTofu 1.7+(循环导入):
# Import multiple resource groups
locals {
resource_groups = {
"rg1" = "/subscriptions/.../resourceGroups/rg1"
"rg2" = "/subscriptions/.../resourceGroups/rg2"
"rg3" = "/subscriptions/.../resourceGroups/rg3"
}
}
import {
for_each = local.resource_groups
to = azurerm_resource_group.imported[each.key]
id = each.value
}
resource "azurerm_resource_group" "imported" {
for_each = local.resource_groups
name = each.key
location = "eastus"
}
提前评估变量(OpenTofu 1.7+)
Terraform 1.5.x:
# Variables NOT allowed in terraform block
terraform {
required_version = ">= 1.5.0" # Static only
backend "azurerm" {
resource_group_name = "terraform-state" # Static only
storage_account_name = "tfstate"
}
}
OpenTofu 1.7+:
# Variables allowed in terraform block
variable "environment" {
type = string
}
terraform {
required_version = ">= 1.7.0"
backend "azurerm" {
resource_group_name = "terraform-state-${var.environment}"
storage_account_name = "tfstate${var.environment}"
key = "${var.environment}.tfstate"
}
}
OpenTofu 1.8+(模块源):
variable "module_version" {
type = string
default = "v1.0.0"
}
module "networking" {
source = "git::https://github.com/org/module.git?ref=${var.module_version}"
# Dynamic module version!
}
实用迁移示例
示例 1:小型项目迁移
# 1. Backup existing state
terraform state pull > backup.tfstate
# 2. Install OpenTofu
brew install opentofu
# 3. Test compatibility
tofu init
tofu plan
# 4. Switch to OpenTofu
alias terraform=tofu # Optional: maintain muscle memory
# 5. Verify everything works
tofu apply
示例 2:使用加密的企业级迁移
# 1. Generate encryption key
ENCRYPTION_KEY=$(openssl rand -base64 32)
echo "TOFU_ENCRYPTION_KEY=$ENCRYPTION_KEY" >> .env.production
# 2. Create encryption config
cat > .tofu <<EOF
encryption {
state {
method = "aes_gcm"
keys {
name = "prod_key"
passphrase = env.TOFU_ENCRYPTION_KEY
}
}
plan {
method = "aes_gcm"
keys {
name = "prod_key"
passphrase = env.TOFU_ENCRYPTION_KEY
}
}
}
EOF
# 3. Migrate with encryption
source .env.production
tofu init -migrate-state
# 4. Verify encryption
tofu state pull # State is now encrypted in backend
示例 3:CI/CD 迁移
# .github/workflows/terraform.yml
name: Infrastructure
on: [push, pull_request]
jobs:
opentofu:
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
env:
TOFU_ENCRYPTION_KEY: ${{ secrets.TOFU_ENCRYPTION_KEY }}
- name: Plan
run: tofu plan
env:
ARM_CLIENT_ID: ${{ secrets.ARM_CLIENT_ID }}
ARM_CLIENT_SECRET: ${{ secrets.ARM_CLIENT_SECRET }}
ARM_SUBSCRIPTION_ID: ${{ secrets.ARM_SUBSCRIPTION_ID }}
ARM_TENANT_ID: ${{ secrets.ARM_TENANT_ID }}
TOFU_ENCRYPTION_KEY: ${{ secrets.TOFU_ENCRYPTION_KEY }}
- name: Apply
if: github.ref == 'refs/heads/main'
run: tofu apply -auto-approve
env:
ARM_CLIENT_ID: ${{ secrets.ARM_CLIENT_ID }}
ARM_CLIENT_SECRET: ${{ secrets.ARM_CLIENT_SECRET }}
ARM_SUBSCRIPTION_ID: ${{ secrets.ARM_SUBSCRIPTION_ID }}
ARM_TENANT_ID: ${{ secrets.ARM_TENANT_ID }}
TOFU_ENCRYPTION_KEY: ${{ secrets.TOFU_ENCRYPTION_KEY }}
命令兼容性
所有 Terraform 命令在 OpenTofu 中的用法完全相同(只需将 terraform 替换为 tofu):
# Terraform # OpenTofu
terraform init → tofu init
terraform plan → tofu plan
terraform apply → tofu apply
terraform destroy → tofu destroy
terraform state → tofu state
terraform import → tofu import
terraform validate → tofu validate
terraform fmt → tofu fmt
terraform output → tofu output
社区与支持
OpenTofu 社区:
- GitHub:https://github.com/opentofu/opentofu
- Slack:OpenTofu 工作区
- 论坛:OpenTofu 讨论区
- 注册表:registry.opentofu.org
Terraform 社区:
- 论坛:HashiCorp 讨论区
- GitHub:hashicorp/terraform
- 注册表:registry.terraform.io
- 支持:HashiCorp 支持门户
决策矩阵
| 因素 | Terraform | OpenTofu |
|---|---|---|
| 许可证 | BSL(专有) | MPL 2.0(开源) |
| 状态加密 | 通过 HCP Terraform 提供(付费) | 内置(免费) |
| 企业级功能 | HCP Terraform(Stacks、HYOK) | 社区替代方案 |
| 治理 | HashiCorp/IBM | Linux Foundation |
| 支持 | 提供商业支持 | 社区驱动 |
| 创新 | 面向 HCP | 面向社区 |
| 成本 | CLI 免费,云服务付费 | 完全免费 |
| 兼容性 | 向前兼容 | 兼容 Terraform 1.5.x |
建议
在以下情况下从 OpenTofu 开始:
- 构建新的基础设施
- 不需要 HCP Terraform 功能
- 希望无需云服务费用即可加密状态
- 倾向于使用开源工具
- 注重预算
在以下情况下继续使用 Terraform:
- 正在使用 HCP Terraform Stacks
- 需要 Sentinel 策略
- 需要企业级支持
- 希望优先获得最新功能(1.10+)
- 已有 HCP 投资
切换轻松:
- 两者长期来看都可行
- 大多数项目的迁移耗时不到 1 小时
- 状态文件可移植
- 可以无承诺地评估两者
此技能为 terraform-expert Agent 提供全面的 OpenTofu 知识。