mcpField
O
opentofu-migration

opentofu-migration

github.com/bagelholeクラウド・DevOps1.2k310 回インストール23 週間前に更新
リポジトリ

opentofu-migration について

Terraformユーザー向けに、インフラコードをOpenTofuへ移行する手順をまとめたスキルです。状態の互換性、コマンドやCI/CDの変更に加え、OpenTofu固有の機能も扱います。

主な機能

  1. 01Terraform状態の互換性確認
  2. 02CLIコマンドの置換とロックファイル更新
  3. 03バックエンドとProvider Registryの確認
  4. 04GitHub ActionsとGitLab CIの更新
  5. 05状態暗号化と変数の早期評価の確認

活用シーン

  1. 01ライセンス上の理由でTerraformからOpenTofuへ移行
  2. 02CI/CDパイプラインをOpenTofu向けに変更
  3. 03新しいIaCプロジェクトでOpenTofuを評価
  4. 04OpenTofu Provider Registryを設定

インストール

コマンドをコピーしてターミナルで実行します。

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

インストール後、Claude Code で/opentofu-migrationを入力して読み込まれたか確認します。

詳細

OpenTofu への移行

HashiCorp Terraform からオープンソースの OpenTofu フォークへ、Infrastructure as Code を移行します。

このスキルを使用する場面

次の場合にこのスキルを使用します。

  • ライセンス上の理由で Terraform から OpenTofu に移行する場合
  • 新しい IaC プロジェクトを立ち上げ、OpenTofu と Terraform を比較検討する場合
  • CI/CD パイプラインを更新して OpenTofu を使用する場合
  • OpenTofu プロバイダーレジストリを設定する場合

前提条件

  • 既存の 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. プロバイダーロックファイルを更新する
# 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. プロバイダーレジストリ

OpenTofu は独自のレジストリを使用しますが、ほとんどの Terraform プロバイダーをミラーしています。

# 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

トラブルシューティング

問題解決策
プロバイダーが見つからないtofu init -upgrade を実行し、registry.opentofu.org を確認します
ステートロックの競合Terraform と同様に、DynamoDB/blob のリースを確認します
バージョン制約エラーrequired_version を >= 1.6.0 に更新します
バックエンドの移行ステートには互換性があります。tofu init を実行するだけです
プロバイダーの認証情報がない同じ環境変数が使えます(AWS_*、GOOGLE_*、ARM_*)

関連スキル

コメント