opentofu-guide

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese
<!-- Progressive Disclosure References: - references/opentofu-1.10-features.md - OCI registry, native S3 locking, deprecation warnings - references/opentofu-1.11-features.md - Ephemeral resources, enabled meta-argument - references/state-encryption.md - Complete state encryption guide with KMS integration -->
<!-- 渐进式披露参考: - references/opentofu-1.10-features.md - OCI注册表、原生S3锁定、弃用警告 - references/opentofu-1.11-features.md - 临时资源、enabled元参数 - references/state-encryption.md - 包含KMS集成的完整状态加密指南 -->

🚨 CRITICAL GUIDELINES

🚨 关键指南

Windows File Path Requirements

Windows文件路径要求

MANDATORY: Always Use Backslashes on Windows for File Paths
When using Edit or Write tools on Windows, you MUST use backslashes (
\
) in file paths, NOT forward slashes (
/
).
Examples:
  • ❌ WRONG:
    D:/repos/project/file.tsx
  • ✅ CORRECT:
    D:\repos\project\file.tsx
This applies to:
  • Edit tool file_path parameter
  • Write tool file_path parameter
  • All file operations on Windows systems
强制要求:Windows系统下文件路径必须使用反斜杠
在Windows系统上使用编辑或写入工具时,文件路径必须使用反斜杠(
\
),而不是正斜杠(
/
)。
示例:
  • ❌ 错误:
    D:/repos/project/file.tsx
  • ✅ 正确:
    D:\repos\project\file.tsx
此要求适用于:
  • 编辑工具的file_path参数
  • 写入工具的file_path参数
  • Windows系统上的所有文件操作

Documentation Guidelines

文档指南

NEVER create new documentation files unless explicitly requested by the user.
  • Priority: Update existing README.md files rather than creating new documentation
  • Repository cleanliness: Keep repository root clean - only README.md unless user requests otherwise
  • Style: Documentation should be concise, direct, and professional - avoid AI-generated tone
  • User preference: Only create additional .md files when user specifically asks for documentation

除非用户明确要求,否则绝不创建新的文档文件。
  • 优先级:优先更新现有README.md文件,而非创建新文档
  • 仓库整洁性:保持仓库根目录整洁 - 除非用户要求,否则仅保留README.md
  • 风格:文档应简洁、直接、专业 - 避免AI生成的语气
  • 用户偏好:仅当用户明确要求文档时,才创建额外的.md文件

OpenTofu Expertise and Migration Guide

OpenTofu专业知识与迁移指南

Overview

概述

OpenTofu is the open-source fork of Terraform, created in 2023 after HashiCorp changed Terraform's license from MPL 2.0 to BSL (Business Source License). OpenTofu is stewarded by the Linux Foundation and maintains full compatibility with Terraform 1.5.x while adding community-driven features.
OpenTofu是Terraform的开源分支,2023年HashiCorp将Terraform的许可证从MPL 2.0改为BSL(商业源代码许可证)后创建。OpenTofu由Linux基金会管理,在保持与Terraform 1.5.x完全兼容的同时,添加了社区驱动的功能。

Key Differences (2025)

主要差异(2025年)

Licensing

许可证

Terraform (HashiCorp):
  • BSL (Business Source License) since August 2023
  • Restrictions on commercial use for competing products
  • IBM acquired HashiCorp in 2024
OpenTofu:
  • MPL 2.0 (Mozilla Public License)
  • True open-source
  • Linux Foundation governance
  • Community-driven development
Terraform(HashiCorp):
  • 自2023年8月起采用BSL(商业源代码许可证)
  • 对竞争产品的商业使用存在限制
  • IBM于2024年收购HashiCorp
OpenTofu:
  • MPL 2.0(Mozilla公共许可证)
  • 真正的开源
  • 由Linux基金会治理
  • 社区驱动的开发

Feature Innovations (2025)

功能创新(2025年)

OpenTofu 1.7 Features:
  • State Encryption: Client-side encryption (community requested for 5+ years)
  • Loop-able Import Blocks: for_each in import blocks
  • Dynamic Provider Functions: Provider-defined functions support
  • Early Variable Evaluation: Variables in terraform block
OpenTofu 1.8 Features (Latest):
  • OpenTofu-Specific Overrides: Balance compatibility with innovation
  • Early Variable Evaluation Expanded: Use variables/locals in module sources
  • Enhanced Provider Support: Improved provider SDK
Terraform Advantages:
  • HCP Terraform: Cloud platform with Stacks, HYOK, Private VCS Access
  • Enterprise Support: Direct HashiCorp/IBM support
  • Larger Ecosystem: More established marketplace
  • Sentinel Policies: Policy-as-code framework (350+ NIST policies)
OpenTofu 1.7功能:
  • 状态加密:客户端加密(社区呼吁超过5年的功能)
  • 可循环的导入块:导入块中支持for_each
  • 动态提供商函数:支持提供商定义的函数
  • 早期变量评估:terraform块中可使用变量
OpenTofu 1.8功能(最新版本):
  • OpenTofu专属覆盖:在兼容性与创新性之间取得平衡
  • 扩展的早期变量评估:模块源中可使用变量/本地值
  • 增强的提供商支持:改进的提供商SDK
Terraform优势:
  • HCP Terraform:包含Stacks、HYOK、私有VCS访问的云平台
  • 企业支持:直接的HashiCorp/IBM支持
  • 更庞大的生态系统:更成熟的市场
  • Sentinel策略:策略即代码框架(包含350+ NIST策略)

Compatibility

兼容性

100% Compatible:
  • HCL syntax (same language)
  • Provider ecosystem (same registry access)
  • State file format (Terraform 1.5.x)
  • Module structure
  • CLI commands
Migration Path:
  • Drop-in replacement for Terraform 1.5.x
  • No code changes required
  • State files portable (with encryption consideration)
100%兼容:
  • HCL语法(相同语言)
  • 提供商生态系统(相同的注册表访问权限)
  • 状态文件格式(Terraform 1.5.x)
  • 模块结构
  • CLI命令
迁移路径:
  • 可直接替换Terraform 1.5.x
  • 无需修改代码
  • 状态文件可移植(需考虑加密因素)

When to Use OpenTofu vs Terraform

何时选择OpenTofu vs Terraform

Choose OpenTofu When:

选择OpenTofu的场景:

  1. Open-Source Requirements:
    • Organization policy requires open-source tools
    • Want vendor neutrality
    • Concerned about future license changes
  2. State Encryption Needed:
    • Compliance requires client-side encryption
    • Want encryption without HCP Terraform
    • Multi-cloud encryption requirements
  3. Cost Optimization:
    • Want free state encryption
    • No need for HCP Terraform features
    • Budget constraints on tooling
  4. Community-Driven:
    • Want to influence roadmap
    • Prefer Linux Foundation governance
    • Value community contributions
  1. 开源需求:
    • 组织政策要求使用开源工具
    • 希望保持供应商中立
    • 担忧未来许可证变更
  2. 需要状态加密:
    • 合规要求客户端加密
    • 希望无需HCP Terraform即可实现加密
    • 多云加密需求
  3. 成本优化:
    • 希望免费使用状态加密
    • 不需要HCP Terraform的功能
    • 工具预算有限
  4. 社区驱动:
    • 希望影响路线图
    • 偏好Linux基金会的治理模式
    • 重视社区贡献

Choose Terraform When:

选择Terraform的场景:

  1. Enterprise Features Required:
    • Need HCP Terraform Stacks
    • Require HYOK (Hold Your Own Key)
    • Want Private VCS Access
    • Need Sentinel policy enforcement
  2. Enterprise Support:
    • Want direct HashiCorp/IBM support
    • Need SLA guarantees
    • Require compliance certifications
  3. Advanced Features:
    • Ephemeral values (1.10+)
    • Terraform Query (1.14+)
    • Actions blocks (1.14+)
    • Latest provider features first
  4. Established Ecosystem:
    • Existing HCP Terraform investment
    • Tight integration needs
    • Mature tooling requirements
  1. 需要企业功能:
    • 需要HCP Terraform Stacks
    • 要求HYOK(自持密钥)
    • 希望使用私有VCS访问
    • 需要Sentinel策略强制执行
  2. 企业支持:
    • 希望获得直接的HashiCorp/IBM支持
    • 需要SLA保障
    • 要求合规认证
  3. 高级功能:
    • 临时值(1.10+版本)
    • Terraform Query(1.14+版本)
    • Actions块(1.14+版本)
    • 优先使用最新的提供商功能
  4. 成熟的生态系统:
    • 已投入使用HCP Terraform
    • 需要紧密的集成
    • 对工具成熟度有要求

Migration from Terraform to OpenTofu

从Terraform迁移到OpenTofu

Step 1: Assess Compatibility

步骤1:评估兼容性

bash
undefined
bash
undefined

Check Terraform version

检查Terraform版本

terraform version
terraform version

Must be 1.5.x or compatible

必须为1.5.x或兼容版本

Check provider versions

检查提供商版本

terraform providers
terraform providers

All providers compatible (same registry)

所有提供商需兼容(相同注册表)

undefined
undefined

Step 2: Install OpenTofu

步骤2:安装OpenTofu

Windows:
powershell
undefined
Windows系统:
powershell
undefined

Chocolatey

Chocolatey

choco install opentofu
choco install opentofu

Scoop

Scoop

scoop install opentofu
scoop install opentofu

Manual

手动安装


**macOS:**
```bash

**macOS系统:**
```bash

Homebrew

Homebrew

brew install opentofu
brew install opentofu

Manual

手动安装


**Linux:**
```bash

**Linux系统:**
```bash

Snap

Snap

snap install opentofu --classic
snap install opentofu --classic

Debian/Ubuntu

Debian/Ubuntu

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/
undefined
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/
undefined

Step 3: Test Compatibility

步骤3:测试兼容性

bash
undefined
bash
undefined

Navigate to Terraform directory

导航到Terraform项目目录

cd /path/to/terraform/project
cd /path/to/terraform/project

Initialize with OpenTofu (non-destructive)

使用OpenTofu初始化(无破坏性)

tofu init
tofu init

Validate configuration

验证配置

tofu validate
tofu validate

Generate plan (compare with Terraform plan)

生成执行计划(与Terraform计划对比)

tofu plan
undefined
tofu plan
undefined

Step 4: Migrate State (Optional)

步骤4:迁移状态(可选)

If NOT using state encryption:
bash
undefined
如果不使用状态加密:
bash
undefined

State is compatible - no migration needed

状态文件兼容 - 无需迁移

Just switch from 'terraform' to 'tofu' commands

只需将命令从'terraform'改为'tofu'

Verify state

验证状态

tofu show

**If ENABLING state encryption:**
```bash
tofu show

**如果启用状态加密:**
```bash

Configure encryption in .tofu file

在.tofu文件中配置加密

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
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"
export TOFU_ENCRYPTION_KEY="your-secure-passphrase"

Migrate state (automatically encrypts)

迁移状态(自动加密)

tofu init -migrate-state
undefined
tofu init -migrate-state
undefined

Step 5: Update CI/CD

步骤5:更新CI/CD

GitHub Actions:
yaml
undefined
GitHub Actions:
yaml
undefined

Before (Terraform)

之前(Terraform)

  • uses: hashicorp/setup-terraform@v3 with: terraform_version: 1.5.0
  • uses: hashicorp/setup-terraform@v3 with: terraform_version: 1.5.0

After (OpenTofu)

之后(OpenTofu)

  • uses: opentofu/setup-opentofu@v1 with: tofu_version: 1.8.0
  • uses: opentofu/setup-opentofu@v1 with: tofu_version: 1.8.0

Or manual install

或手动安装


**Azure DevOps:**
```yaml

**Azure DevOps:**
```yaml

Before

之前

  • task: TerraformInstaller@0 inputs: terraformVersion: '1.5.0'
  • task: TerraformInstaller@0 inputs: terraformVersion: '1.5.0'

After

之后


**GitLab CI:**
```yaml

**GitLab CI:**
```yaml

Before

之前

image: hashicorp/terraform:1.5.0
image: hashicorp/terraform:1.5.0

After

之后

image: ghcr.io/opentofu/opentofu:1.8.0
undefined
image: ghcr.io/opentofu/opentofu:1.8.0
undefined

State Encryption (OpenTofu Exclusive)

状态加密(OpenTofu专属)

Configuration

配置

Basic Encryption:
hcl
undefined
基础加密:
hcl
undefined

.tofu or terraform.tf

.tofu或terraform.tf

encryption { state { method = "aes_gcm" keys { name = "primary_key" passphrase = env.TOFU_STATE_ENCRYPTION_KEY } } }

**Key Rotation:**
```hcl
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
      }
    }
  }
}
Cloud KMS Integration:
hcl
undefined
encryption { state { method = "aes_gcm" keys { name = "primary_key" passphrase = env.TOFU_STATE_ENCRYPTION_KEY } } }

**密钥轮换:**
```hcl
encryption {
  state {
    method = "aes_gcm"
    keys {
      # 新密钥
      name = "key_v2"
      passphrase = env.TOFU_KEY_V2

      # 旧密钥(用于解密)
      fallback {
        name = "key_v1"
        passphrase = env.TOFU_KEY_V1
      }
    }
  }
}
云KMS集成:
hcl
undefined

AWS 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" } } }
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

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" } } }
encryption { state { method = "azurerm_key_vault" keys { name = "azure_key" key_vault_key_id = "https://myvault.vault.azure.net/keys/mykey/version" } } }

GCP KMS

GCP KMS

encryption { state { method = "gcp_kms" keys { name = "gcp_key" kms_crypto_key = "projects/PROJECT_ID/locations/LOCATION/keyRings/RING/cryptoKeys/KEY" } } }
undefined
encryption { state { method = "gcp_kms" keys { name = "gcp_key" kms_crypto_key = "projects/PROJECT_ID/locations/LOCATION/keyRings/RING/cryptoKeys/KEY" } } }
undefined

Best Practices

最佳实践

  1. Store Keys Securely:
    bash
    # 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
  2. Rotate Keys Regularly:
    bash
    # Generate new key
    NEW_KEY=$(openssl rand -base64 32)
    
    # Add to fallback, update configs
    # Migrate state
    tofu init -migrate-state
  3. Backup Unencrypted State:
    bash
    # Before enabling encryption
    terraform state pull > backup-unencrypted.tfstate
    
    # Enable encryption
    tofu init -migrate-state
    
    # Verify
    tofu state pull  # Should be encrypted in backend
  1. 安全存储密钥:
    bash
    # 绝不要提交密钥
    echo "TOFU_ENCRYPTION_KEY=xxx" >> .env
    echo ".env" >> .gitignore
    
    # 使用CI/CD密钥
    # GitHub:仓库设置 → 密钥
    # Azure DevOps:流水线 → 变量 → 密钥
  2. 定期轮换密钥:
    bash
    # 生成新密钥
    NEW_KEY=$(openssl rand -base64 32)
    
    # 添加到回退配置,更新配置文件
    # 迁移状态
    tofu init -migrate-state
  3. 备份未加密状态:
    bash
    # 启用加密前
    terraform state pull > backup-unencrypted.tfstate
    
    # 启用加密
    tofu init -migrate-state
    
    # 验证
    tofu state pull  # 后端中的状态应已加密

Loop-able Import Blocks (OpenTofu 1.7+)

可循环的导入块(OpenTofu 1.7+)

Terraform 1.5+ (Single Imports):
hcl
import {
  to = azurerm_resource_group.example
  id = "/subscriptions/.../resourceGroups/my-rg"
}
OpenTofu 1.7+ (Loop Imports):
hcl
undefined
Terraform 1.5+(单次导入):
hcl
import {
  to = azurerm_resource_group.example
  id = "/subscriptions/.../resourceGroups/my-rg"
}
OpenTofu 1.7+(循环导入):
hcl
undefined

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" }
undefined
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" }
undefined

Early Variable Evaluation (OpenTofu 1.7+)

早期变量评估(OpenTofu 1.7+)

Terraform 1.5.x:
hcl
undefined
Terraform 1.5.x:
hcl
undefined

Variables NOT allowed in terraform block

terraform块中不允许使用变量

terraform { required_version = ">= 1.5.0" # Static only
backend "azurerm" { resource_group_name = "terraform-state" # Static only storage_account_name = "tfstate" } }

**OpenTofu 1.7+:**
```hcl
terraform { required_version = ">= 1.5.0" # 仅支持静态值
backend "azurerm" { resource_group_name = "terraform-state" # 仅支持静态值 storage_account_name = "tfstate" } }

**OpenTofu 1.7+:**
```hcl

Variables allowed in terraform block

terraform块中允许使用变量

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+ (Module Sources):**
```hcl
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!
}
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+(模块源):**
```hcl
variable "module_version" {
  type    = string
  default = "v1.0.0"
}

module "networking" {
  source  = "git::https://github.com/org/module.git?ref=${var.module_version}"
  # 动态模块版本!
}

Practical Migration Examples

实际迁移示例

Example 1: Small Project Migration

示例1:小型项目迁移

bash
undefined
bash
undefined

1. Backup existing state

1. 备份现有状态

terraform state pull > backup.tfstate
terraform state pull > backup.tfstate

2. Install OpenTofu

2. 安装OpenTofu

brew install opentofu
brew install opentofu

3. Test compatibility

3. 测试兼容性

tofu init tofu plan
tofu init tofu plan

4. Switch to OpenTofu

4. 切换到OpenTofu

alias terraform=tofu # Optional: maintain muscle memory
alias terraform=tofu # 可选:保持操作习惯

5. Verify everything works

5. 验证所有功能正常

tofu apply
undefined
tofu apply
undefined

Example 2: Enterprise Migration with Encryption

示例2:带加密的企业迁移

bash
undefined
bash
undefined

1. Generate encryption key

1. 生成加密密钥

ENCRYPTION_KEY=$(openssl rand -base64 32) echo "TOFU_ENCRYPTION_KEY=$ENCRYPTION_KEY" >> .env.production
ENCRYPTION_KEY=$(openssl rand -base64 32) echo "TOFU_ENCRYPTION_KEY=$ENCRYPTION_KEY" >> .env.production

2. Create encryption config

2. 创建加密配置

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
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

3. 带加密的迁移

source .env.production tofu init -migrate-state
source .env.production tofu init -migrate-state

4. Verify encryption

4. 验证加密

tofu state pull # State is now encrypted in backend
undefined
tofu state pull # 后端中的状态现在已加密
undefined

Example 3: CI/CD Migration

示例3:CI/CD迁移

yaml
undefined
yaml
undefined

.github/workflows/terraform.yml

.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 }}
undefined
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 }}
undefined

Command Compatibility

命令兼容性

All Terraform commands work identically in OpenTofu (just replace
terraform
with
tofu
):
bash
undefined
所有Terraform命令在OpenTofu中完全相同(只需将
terraform
替换为
tofu
):
bash
undefined

Terraform # OpenTofu

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
undefined
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
undefined

Community and Support

社区与支持

OpenTofu Community:
Terraform Community:
  • Forum: HashiCorp Discuss
  • GitHub: hashicorp/terraform
  • Registry: registry.terraform.io
  • Support: HashiCorp Support Portal
OpenTofu社区:
Terraform社区:
  • 论坛:HashiCorp讨论区
  • GitHub:hashicorp/terraform
  • 注册表:registry.terraform.io
  • 支持:HashiCorp支持门户

Decision Matrix

决策矩阵

FactorTerraformOpenTofu
LicenseBSL (Proprietary)MPL 2.0 (Open Source)
State EncryptionVia HCP Terraform (paid)Built-in (free)
Enterprise FeaturesHCP Terraform (Stacks, HYOK)Community alternatives
GovernanceHashiCorp/IBMLinux Foundation
SupportCommercial support availableCommunity-driven
InnovationHCP-focusedCommunity-focused
CostFree CLI, paid cloudCompletely free
CompatibilityForward-compatibleTerraform 1.5.x compatible
因素TerraformOpenTofu
许可证BSL(专有)MPL 2.0(开源)
状态加密通过HCP Terraform(付费)内置(免费)
企业功能HCP Terraform(Stacks、HYOK)社区替代方案
治理HashiCorp/IBMLinux基金会
支持提供商业支持社区驱动
创新聚焦HCP聚焦社区
成本CLI免费,云服务付费完全免费
兼容性向前兼容兼容Terraform 1.5.x

Recommendations

建议

Start with OpenTofu if:
  • Building new infrastructure
  • No need for HCP Terraform features
  • Want state encryption without cloud costs
  • Prefer open-source tools
  • Budget-conscious
Stay with Terraform if:
  • Using HCP Terraform Stacks
  • Need Sentinel policies
  • Require enterprise support
  • Want latest features first (1.10+)
  • Established HCP investment
Easy to Switch:
  • Both are viable long-term
  • Migration takes < 1 hour for most projects
  • State files portable
  • Can evaluate both without commitment
This skill provides comprehensive OpenTofu knowledge for the terraform-expert agent.
如果符合以下情况,从OpenTofu开始:
  • 构建新的基础设施
  • 不需要HCP Terraform的功能
  • 希望无需云成本即可实现状态加密
  • 偏好开源工具
  • 预算有限
如果符合以下情况,继续使用Terraform:
  • 使用HCP Terraform Stacks
  • 需要Sentinel策略
  • 要求企业支持
  • 希望优先使用最新功能(1.10+)
  • 已投入HCP
切换很简单:
  • 两者都是长期可行的选择
  • 大多数项目迁移耗时不到1小时
  • 状态文件可移植
  • 无需承诺即可同时评估两者
本技能为terraform-expert代理提供全面的OpenTofu知识。