mcpField
O
opentofu-migration

opentofu-migration

github.com/bagelhole云与 DevOps1.2k310 次安装23 周前更新
代码仓库

关于 opentofu-migration

面向 Terraform 用户的迁移技能,指导将基础设施即代码项目切换到 OpenTofu。内容涵盖状态兼容性、命令与 CI/CD 更新,以及 OpenTofu 特有功能。

主要功能

  1. 01检查 Terraform 状态兼容性
  2. 02替换 CLI 命令并更新锁文件
  3. 03验证后端与 Provider Registry
  4. 04更新 GitHub Actions 和 GitLab CI
  5. 05介绍状态加密与早期变量求值

适用场景

  1. 01因许可原因将项目从 Terraform 迁至 OpenTofu
  2. 02调整 CI/CD 流水线以运行 OpenTofu
  3. 03在新 IaC 项目中评估 OpenTofu
  4. 04配置 OpenTofu Provider Registry

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/bagelhole/devops-security-agent-skills --skill opentofu-migration

安装后在 Claude Code 中输入/opentofu-migration确认已加载。

详细介绍

OpenTofu 迁移

将基础设施即代码从 HashiCorp Terraform 迁移到开源的 OpenTofu 分支。

何时使用此技能

在以下情况下使用此技能:

  • 因许可原因从 Terraform 迁移到 OpenTofu
  • 创建新的 IaC 项目并评估 OpenTofu 与 Terraform
  • 更新 CI/CD 流水线以使用 OpenTofu
  • 配置 OpenTofu Provider Registry

前提条件

  • 现有的 Terraform 代码库(0.13+)
  • 已安装 OpenTofu CLI
  • 可访问状态后端(S3、GCS、Azure Blob 等)

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

迁移清单

1. 验证兼容性
# 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. 替换 CLI 命令
TerraformOpenTofu
terraform inittofu init
terraform plantofu plan
terraform applytofu apply
terraform destroytofu destroy
terraform fmttofu fmt
terraform validatetofu validate
terraform statetofu state
terraform importtofu import
3. 更新 Provider 锁定文件
# Remove Terraform lock and regenerate for OpenTofu
rm .terraform.lock.hcl
tofu init -upgrade

# Verify providers resolve correctly
tofu providers
4. 更新状态后端

状态文件兼容,无需迁移。只需验证:

# 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 使用自己的 Registry,但镜像了大多数 Terraform Provider:

# 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 专属功能

状态加密(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
    }
  }
}
提前求值变量/局部值
# 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 流水线

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]

共存策略

如果迁移期间需要同时使用这两种工具:

# 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

故障排除

问题解决方案
未找到 Provider运行 tofu init -upgrade,检查 registry.opentofu.org
状态锁冲突与 Terraform 相同——检查 DynamoDB/blob 租约
版本约束错误将 required_version 更新为 >= 1.6.0
后端迁移状态兼容——只需运行 tofu init
缺少 Provider 凭据相同的环境变量可用(AWS_*、GOOGLE_*、ARM_*)

相关技能

评论

支持 Markdown