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的场景:
-
Open-Source Requirements:
- Organization policy requires open-source tools
- Want vendor neutrality
- Concerned about future license changes
-
State Encryption Needed:
- Compliance requires client-side encryption
- Want encryption without HCP Terraform
- Multi-cloud encryption requirements
-
Cost Optimization:
- Want free state encryption
- No need for HCP Terraform features
- Budget constraints on tooling
-
Community-Driven:
- Want to influence roadmap
- Prefer Linux Foundation governance
- Value community contributions
-
开源需求:
- 组织政策要求使用开源工具
- 希望保持供应商中立
- 担忧未来许可证变更
-
需要状态加密:
- 合规要求客户端加密
- 希望无需HCP Terraform即可实现加密
- 多云加密需求
-
成本优化:
- 希望免费使用状态加密
- 不需要HCP Terraform的功能
- 工具预算有限
-
社区驱动:
- 希望影响路线图
- 偏好Linux基金会的治理模式
- 重视社区贡献
Choose Terraform When:
选择Terraform的场景:
-
Enterprise Features Required:
- Need HCP Terraform Stacks
- Require HYOK (Hold Your Own Key)
- Want Private VCS Access
- Need Sentinel policy enforcement
-
Enterprise Support:
- Want direct HashiCorp/IBM support
- Need SLA guarantees
- Require compliance certifications
-
Advanced Features:
- Ephemeral values (1.10+)
- Terraform Query (1.14+)
- Actions blocks (1.14+)
- Latest provider features first
-
Established Ecosystem:
- Existing HCP Terraform investment
- Tight integration needs
- Mature tooling requirements
-
需要企业功能:
- 需要HCP Terraform Stacks
- 要求HYOK(自持密钥)
- 希望使用私有VCS访问
- 需要Sentinel策略强制执行
-
企业支持:
- 希望获得直接的HashiCorp/IBM支持
- 需要SLA保障
- 要求合规认证
-
高级功能:
- 临时值(1.10+版本)
- Terraform Query(1.14+版本)
- Actions块(1.14+版本)
- 优先使用最新的提供商功能
-
成熟的生态系统:
- 已投入使用HCP Terraform
- 需要紧密的集成
- 对工具成熟度有要求
Migration from Terraform to OpenTofu
从Terraform迁移到OpenTofu
Step 1: Assess Compatibility
步骤1:评估兼容性
bash
undefinedbash
undefinedCheck 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)
所有提供商需兼容(相同注册表)
undefinedundefinedStep 2: Install OpenTofu
步骤2:安装OpenTofu
Windows:
powershell
undefinedWindows系统:
powershell
undefinedChocolatey
Chocolatey
choco install opentofu
choco install opentofu
Scoop
Scoop
scoop install opentofu
scoop install opentofu
Manual
手动安装
Download from https://github.com/opentofu/opentofu/releases
**macOS:**
```bash
**macOS系统:**
```bashHomebrew
Homebrew
brew install opentofu
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:**
```bashcurl -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系统:**
```bashSnap
Snap
snap install opentofu --classic
snap install opentofu --classic
Debian/Ubuntu
Debian/Ubuntu
curl -fsSL https://get.opentofu.org/install-opentofu.sh | sh
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/
undefinedwget 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/
undefinedStep 3: Test Compatibility
步骤3:测试兼容性
bash
undefinedbash
undefinedNavigate 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
undefinedtofu plan
undefinedStep 4: Migrate State (Optional)
步骤4:迁移状态(可选)
If NOT using state encryption:
bash
undefined如果不使用状态加密:
bash
undefinedState is compatible - no migration needed
状态文件兼容 - 无需迁移
Just switch from 'terraform' to 'tofu' commands
只需将命令从'terraform'改为'tofu'
Verify state
验证状态
tofu show
**If ENABLING state encryption:**
```bashtofu show
**如果启用状态加密:**
```bashConfigure 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
undefinedtofu init -migrate-state
undefinedStep 5: Update CI/CD
步骤5:更新CI/CD
GitHub Actions:
yaml
undefinedGitHub Actions:
yaml
undefinedBefore (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
或手动安装
- name: Install OpenTofu run: | curl -fsSL https://get.opentofu.org/install-opentofu.sh | sh tofu version
**Azure DevOps:**
```yaml- name: Install OpenTofu run: | curl -fsSL https://get.opentofu.org/install-opentofu.sh | sh tofu version
**Azure DevOps:**
```yamlBefore
之前
- task: TerraformInstaller@0 inputs: terraformVersion: '1.5.0'
- 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:**
```yaml- task: Bash@3 displayName: 'Install OpenTofu' inputs: targetType: 'inline' script: | curl -fsSL https://get.opentofu.org/install-opentofu.sh | sh tofu version
**GitLab CI:**
```yamlBefore
之前
image: hashicorp/terraform:1.5.0
image: hashicorp/terraform:1.5.0
After
之后
image: ghcr.io/opentofu/opentofu:1.8.0
undefinedimage: ghcr.io/opentofu/opentofu:1.8.0
undefinedState 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
undefinedencryption {
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
undefinedAWS 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"
}
}
}
undefinedencryption {
state {
method = "gcp_kms"
keys {
name = "gcp_key"
kms_crypto_key = "projects/PROJECT_ID/locations/LOCATION/keyRings/RING/cryptoKeys/KEY"
}
}
}
undefinedBest Practices
最佳实践
-
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 -
Rotate Keys Regularly:bash
# Generate new key NEW_KEY=$(openssl rand -base64 32) # Add to fallback, update configs # Migrate state tofu init -migrate-state -
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
-
安全存储密钥:bash
# 绝不要提交密钥 echo "TOFU_ENCRYPTION_KEY=xxx" >> .env echo ".env" >> .gitignore # 使用CI/CD密钥 # GitHub:仓库设置 → 密钥 # Azure DevOps:流水线 → 变量 → 密钥 -
定期轮换密钥:bash
# 生成新密钥 NEW_KEY=$(openssl rand -base64 32) # 添加到回退配置,更新配置文件 # 迁移状态 tofu init -migrate-state -
备份未加密状态: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
undefinedTerraform 1.5+(单次导入):
hcl
import {
to = azurerm_resource_group.example
id = "/subscriptions/.../resourceGroups/my-rg"
}OpenTofu 1.7+(循环导入):
hcl
undefinedImport 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"
}
undefinedlocals {
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"
}
undefinedEarly Variable Evaluation (OpenTofu 1.7+)
早期变量评估(OpenTofu 1.7+)
Terraform 1.5.x:
hcl
undefinedTerraform 1.5.x:
hcl
undefinedVariables 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+:**
```hclterraform {
required_version = ">= 1.5.0" # 仅支持静态值
backend "azurerm" {
resource_group_name = "terraform-state" # 仅支持静态值
storage_account_name = "tfstate"
}
}
**OpenTofu 1.7+:**
```hclVariables 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
undefinedbash
undefined1. 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
undefinedtofu apply
undefinedExample 2: Enterprise Migration with Encryption
示例2:带加密的企业迁移
bash
undefinedbash
undefined1. 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
undefinedtofu state pull # 后端中的状态现在已加密
undefinedExample 3: CI/CD Migration
示例3:CI/CD迁移
yaml
undefinedyaml
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 }}undefinedname: 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 }}undefinedCommand Compatibility
命令兼容性
All Terraform commands work identically in OpenTofu (just replace with ):
terraformtofubash
undefined所有Terraform命令在OpenTofu中完全相同(只需将替换为):
terraformtofubash
undefinedTerraform # 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
undefinedterraform 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
undefinedCommunity and Support
社区与支持
OpenTofu Community:
- GitHub: https://github.com/opentofu/opentofu
- Slack: OpenTofu Workspace
- Forum: OpenTofu Discussions
- Registry: registry.opentofu.org
Terraform Community:
- Forum: HashiCorp Discuss
- GitHub: hashicorp/terraform
- Registry: registry.terraform.io
- Support: HashiCorp Support Portal
OpenTofu社区:
- GitHub:https://github.com/opentofu/opentofu
- Slack:OpenTofu工作区
- 论坛:OpenTofu讨论区
- 注册表:registry.opentofu.org
Terraform社区:
- 论坛:HashiCorp讨论区
- GitHub:hashicorp/terraform
- 注册表:registry.terraform.io
- 支持:HashiCorp支持门户
Decision Matrix
决策矩阵
| Factor | Terraform | OpenTofu |
|---|---|---|
| License | BSL (Proprietary) | MPL 2.0 (Open Source) |
| State Encryption | Via HCP Terraform (paid) | Built-in (free) |
| Enterprise Features | HCP Terraform (Stacks, HYOK) | Community alternatives |
| Governance | HashiCorp/IBM | Linux Foundation |
| Support | Commercial support available | Community-driven |
| Innovation | HCP-focused | Community-focused |
| Cost | Free CLI, paid cloud | Completely free |
| Compatibility | Forward-compatible | Terraform 1.5.x compatible |
| 因素 | Terraform | OpenTofu |
|---|---|---|
| 许可证 | BSL(专有) | MPL 2.0(开源) |
| 状态加密 | 通过HCP Terraform(付费) | 内置(免费) |
| 企业功能 | HCP Terraform(Stacks、HYOK) | 社区替代方案 |
| 治理 | HashiCorp/IBM | Linux基金会 |
| 支持 | 提供商业支持 | 社区驱动 |
| 创新 | 聚焦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知识。