opentofu-guide について
Terraform ユーザーやインフラチーム向けの OpenTofu 解説・移行ガイドです。互換性や相違点、移行手順に加え、状態の暗号化、ループ可能なインポート、変数評価などを扱います。
主な機能
- 01Terraform と OpenTofu の違い
- 02移行時の互換性評価
- 03状態暗号化の設定
- 04ループ可能なインポートブロック例
- 05変数とモジュールソースの評価
活用シーン
- 01Terraform からの移行可否の評価
- 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 は、HashiCorp が 2023 年に Terraform のライセンスを MPL 2.0 から BSL(Business Source License)に変更した後に作成された、Terraform のオープンソースフォークです。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 の機能:
- State の暗号化:クライアント側の暗号化(5 年以上にわたりコミュニティから要望)
- ループ可能なインポートブロック:インポートブロックでの for_each
- 動的なプロバイダー関数:プロバイダー定義関数のサポート
- 早期の変数評価:terraform ブロックでの変数
OpenTofu 1.8 の機能(最新):
- OpenTofu 固有のオーバーライド:互換性と革新性のバランス
- 早期の変数評価の拡張:モジュールソースでの変数/ローカル値の使用
- プロバイダーサポートの強化:プロバイダー SDK の改善
Terraform の利点:
- HCP Terraform:Stacks、HYOK、Private VCS Access を備えたクラウドプラットフォーム
- エンタープライズサポート:HashiCorp/IBM による直接サポート
- より大きなエコシステム:より確立されたマーケットプレイス
- Sentinel Policies:ポリシー・アズ・コードのフレームワーク(NIST ポリシー 350 件以上)
互換性
100%互換:
- HCL 構文(同じ言語)
- プロバイダーエコシステム(同じレジストリアクセス)
- State ファイル形式(Terraform 1.5.x)
- モジュール構造
- CLI コマンド
移行方法:
- Terraform 1.5.x のドロップイン置換
- コードの変更は不要
- State ファイルを移植可能(暗号化に関する考慮事項あり)
OpenTofu と Terraform の選び方
OpenTofu を選ぶ場合:
-
オープンソースの要件:
- 組織のポリシーでオープンソースツールが必要
- ベンダー中立性を重視
- 将来のライセンス変更を懸念
-
State の暗号化が必要:
- コンプライアンス要件でクライアント側の暗号化が必要
- HCP Terraform を使わずに暗号化したい
- マルチクラウドの暗号化要件がある
-
コストの最適化:
- 無料の State 暗号化を利用したい
- HCP Terraform の機能が不要
- ツールの予算に制約がある
-
コミュニティ主導:
- ロードマップに影響を与えたい
- Linux Foundation のガバナンスを希望
- コミュニティからの貢献を重視
次の場合は Terraform を選択してください:
-
エンタープライズ機能が必要な場合:
- HCP Terraform Stacks が必要
- HYOK(Hold Your Own Key)が必要
- プライベート 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 Workspace
- フォーラム:OpenTofu Discussions
- レジストリ:registry.opentofu.org
Terraform コミュニティ:
- フォーラム:HashiCorp Discuss
- GitHub:hashicorp/terraform
- レジストリ:registry.terraform.io
- サポート:HashiCorp Support Portal
判断基準
| 要素 | 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 エージェント向けに OpenTofu の包括的な知識を提供します。