はじめに
この記事は クラウドワークスグループ Advent Calendar 2025 シリーズ1 の 18日目の記事です。
あるときはTerraform職人、またあるときはお豆腐職人の @minamijoyo です。
2023年8月HashiCorpはこれまでMPL2のOSSライセンスで公開していた主要製品をBSL(Business Source License)に変更することを発表し、Terraformはv1.6.0からOSSではなくなりました。このライセンス変更を受けて、OSS版のTerraformを求める人たちで、MPL2時点のコードベースからforkしたOpenTofuの開発が進められています。
これまでに「Terraform職人のためのOpenTofu入門」と「Terraform職人のためのOpenTofu再入門2024」を書きましたが、またすぐに情報が古くなってしまったので、今年も改訂版を書いておこうかなと思います。
「TerraformとOpenTofuって何が違うんですか?」に対する短い答えは、「terraform init / plan / applyを、tofu init / plan / applyに読み替えれば大体同じ」です。というのもOpenTofuはTerraformのforkなので、ここ最近追加されたTerraform v1.6以降の新機能を使っていなければ、今のところはほぼ同じです。OpenTofuはTerraform互換を謳っており、Terraform v1.6以降に追加された機能も需要があれば随時実装されています。
また、ただのクローンではなく、OpenTofuにしかない新機能も追加されています。特にTerraformで長年未解決だったissueが、OpenTofuでも再度議論されてOpenTofu側にだけ取り込まれているものも多々あります。純粋なOSSライセンスであることに興味がない人でも、欲しい機能があるならOpenTofuは検討に値するでしょう。この記事では、OpenTofuの採用を検討しているTerraform職人が押さえておくべきポイントをまとめます。
本稿執筆時点のOpenTofuのバージョンはv1.11.1、Terraformのバージョンはv1.14.3です。まだ検討中の機能などに関しては、関連するissueへのリンクも貼っておきます。気になるトピックの最新の情報は、そちらも合わせてご確認下さい。
OpenTofuプロジェクトの概要
OpenTofuはTerraformのBSLライセンス変更前のMPL2のコードベース(Terraform v1.6.0-alpha相当)からforkされた、OSSのインフラ構成管理ツールです。Linux Foundation傘下のプロジェクトとして、引き続きMPL2ライセンスで開発が進められています。またCNCF(Cloud Native Computing Foundation)のSandboxプロジェクトとしても登録されています。
公式サイト: https://opentofu.org
リポジトリ: https://github.com/opentofu/opentofu
Terraformのdrop-in replacementを謳っており、既存のTerraformのtfファイルやtfstateがほぼそのまま使えます。Terraformとの機能面での違いについては後述します。
コミュニティベースのOSSプロジェクトですが、本稿執筆時点では、Steering CommitteeとしてSpacelift、env0、Scalr、Harness、Gruntworkの5社が中心となって開発を進めています。
OpenTofuの開発チームはHCP Terraform(旧Terraform Cloud)の競合サービスを開発しており、お互いはライバル同士でもあります。特定の1社が強い権限を持ちすぎないように、プロジェクトの運営には一定のガバナンスが必要です。
どの機能を実装すべきかについては、コミュニティから投票を受け付けて優先順位を決めており、重要な設計上の変更には、事前にRFC(Request For Comments)という公開設計レビューを行い、最終的にSteering Committeeにより判断するというプロセスを導入しています。このようにライセンスだけではなく、オープンなスタイルで開発されているのも特徴です。
OpenTofuプロジェクトの歴史
Terraformのライセンス変更から、forkの爆誕までの経緯などは以前書いたので、詳細は以下の記事を参照して下さい。
ここでは過去の経緯は簡単にサマリし、リリース後の開発の状況などを時系列で見ていきます。
HashiCorpのライセンス変更
2023/08/10 HashiCorpはこれまでMPL2のOSSライセンスで公開していた主要製品をBSL(Business Source License)に変更することを発表しました。
注: ソフトウェアのメタデータの標準化を推進しているSPDX(Software Package Data Exchange)では、HashiCorpのBSLの元になったMariaDBのBSLのライセンスの識別子としてBUSL-1.1が付与されてます。一方SPDXでBSLはBoost Software Licenseを指し、こちらはOSI(Open Source Initiative)に承認されたOSSライセンスですので、区別したい場合はBUSLと表記します。この記事では、HashiCorpがBSLと呼んでいるので、特に区別せずBSLと表記します。
最新版のライセンスの全文は以下で確認できます。
https://www.hashicorp.com/bsl
ライセンス文言は厳密にはリリースバージョンごとに管理されています。
https://github.com/hashicorp/terraform/blob/v1.6.0/LICENSE
Terraformのコンテキストに限定してざっくり言うと、HCP Terraform(旧Terraform Cloud)の競合サービスには使わないでねという理解でよい認識ですが、私は法律の専門家ではないので、ライセンスの解釈については各自の責任で判断して下さい。
OpenTofuプロジェクトの誕生
HashiCorpのライセンス変更の発表からほどなく、Terraform関連ベンダの連合がOpenTF Manifestoという文書を公開しました。これはTerraformのライセンス変更に対する反対表明で、元のOSSライセンスに戻してくれなければforkするよという内容のものでした。
しかしながら、HashiCorpから回答がもらえなかったので、ライセンス変更前のコードベース(Terraform v1.6.0-alpha相当)からforkした、OpenTFプロジェクトを公開しました。
このプロジェクトは当初OpenTFという名前でしたが、「TF」という文字列だけでも商標侵害リスクがあるとの懸念が出てきて、コミュニティで新しい名前を募集したところ、「tofuでいいんじゃない。略したらtfだし、terraformとも響きが違う」というネタなのか本気なのか分からない意見が圧倒的な支持を得て、2023/09/20 Linux Foundation傘下に入るタイミングでOpenTofuへリネームされました。
HashiCorpのBSLは、実質的に競合他社の商用利用に制限をかけたものです。ライセンス変更の直接的な影響を受けるユーザは極めて少数であるにも関わらず、Linux Foundation傘下のプロジェクトとして受け入れられ、なぜこれほどまでの支持を受けているのか不思議に思う人もいるかもしれません。それは競合かどうかを決めるのがHashiCorpである、という曖昧さの残るライセンスに依存するのはリスクであると多くの人が考えているからです。特にTerraformのライセンス変更は、クラウドコンピューティングのSPOF (Single Point Of Failure) となっており、ベンダーニュートラルなOSSの選択肢を維持することの重要性が改めて認識された結果と言えるでしょう。
OpenTofu v1.6
2023年12月にOpenTofu Registryが完成し、2024/01/10に最初の安定版であるOpenTofu v1.6.0がリリースされました。ただリネームしただけではなく、Terraform v1.6に入ったtestフレームワークや、s3バックエンドの変更なども実装されました。
OpenTofu v1.7
fork直後のOpenTofu v1.6は、ほぼTerraform v1.6でしたが、2024/04/30に出たOpenTofu v1.7では、OpenTofu独自の新機能として、tfstateのクライアントサイド暗号化機能が追加されました。これはTerraformで何年も前から提案されていたものの、結局取り込まれなかったものです。
また、Terraform v1.7に追加されたremoveブロックや、importブロックのfor_each、Terraform v1.8に追加されたプロバイダ定義関数なども実装されました。
OpenTofu v1.8
2024/07/29に出たOpenTofu v1.8では、OpenTofu独自の新機能として、backendやmodule sourceで部分的にvariableとlocal変数が利用可能になりました。また、新しく.tofu拡張子を導入し、OpenTofu独自の構文を別のファイルに分けて書くことができるようになりました。その他、Terraform v1.7に入っていたが、OpenTofu v1.7に入ってなかったtestフレームワークのモック機能などが実装されました。
apparentlymart氏の移籍
Terraformコアチームのapparentlymart氏が2024年7月にHashiCorpを退職し、10月からSpaceliftに転職し、OpenTofu陣営に移籍しました。
apparentlymart(Martin Atkins)氏が何者か知らない人のために補足しておくと、HCLとTerraformの生みの親はもちろんmitchellh(Mitchell Hashimoto)氏ですが、HCL2とTerraform v0.12以降は彼がほとんど書き直したと言っても過言ではないぐらい、現役のTerraform開発の中心人物でした。
これの意味するところは、OpenTofu陣営はその気になればhashicorp/hclもforkできるし、HCL2の基礎となっている型システムであるzclconf/go-ctyも彼の作品です。そしてgo-ctyはhashicorp/管理下にないという重要なパズルのピースを握っています。
もちろんTerraformはコアだけ成り立っているわけではなく、周辺のエコシステムは引き続きHashiCorpが握っていますし、クラウドベンダの協力なくして豊富なプラグインは維持できません。ただ少なくとも彼の移籍により、OpenTofu陣営はコードベースに知見がないのでアーキテクチャレベルの根本的な改修ができないのではないか、という技術面での懸念は晴れたと言えるでしょう。
OpenTofu v1.9
2025/01/10に出たOpenTofu v1.9では、OpenTofu独自の新機能として、provider for_eachやtofu apply -excludeフラグなど、Terraformで長年未解決だったissueがいくつか実装されました。また、Terraform v1.8に入っていたモジュール入力変数で他の変数が参照可能になる機能なども実装されました。
CNCF Sandboxプロジェクトとして承認
2025/04/23 OpenTofuはCNCF(Cloud Native Computing Foundation)のSandboxプロジェクトとして承認されました。
コンテナ技術やKubernetes関連のエコシステムであるCNCFも、組織構造的にはLinux Foundation傘下で、AWS、Google、Microsoftなど主要なクラウドベンダが名を連ねています。
CNCFへの参加はOpenTofuのプロジェクトの立ち上げ当初から提案されていたものですが、ずいぶんと時間がかかりました。プロジェクト初期は存続が不透明であったことに加え、OpenTofuはMPL2ライセンスだがCNCFは原則Apache2というのもネックでした。最終的にはCNCFのエコシステムに戦略的に有益なプロジェクトということで例外が適用され承認されました。
OpenTofu v1.10
2025/06/23に出たOpenTofu v1.10では、プロバイダとモジュールの置き場として、OCI (Open Container Initiative) Registryが使えるようになりました。OpenTofu Registryをセルフホストするのはちょっと心理的ハードルが高いですが、OCI Registry(=いわゆるDockerイメージ置き場)は既に何かしら使っていることも多いです。カスタムのプロバイダやモジュールを配布する以外にも、インターネットアクセスが制限されている環境で、Public OpenTofu Registryのミラーとして使うようなユースケースも想定されています。
その他、モジュールの入出力変数をdeprecatedとマークする構文が導入されたり、Terraform v1.10に入っていた、S3-native state lockingなども実装されました。
OpenTofu v1.11
2025/12/10に出たOpenTofu v1.11では、lifecycleブロックにenabled属性が追加され、従来のcountを使ったリソースの有効化/無効化をより直感的に書けるようになりました。その他、Terraform v1.10のEphemeral valuesとTerraform v1.11のWrite-only attributesも実装されました。
TerraformからOpenTofuへの移行
TerraformからOpenTofuへの公式の移行ガイドは以下にあります。
https://opentofu.org/docs/intro/migration/
基本的にTerraform v1.5までの機能しか使っていなければ、terraform applyして差分がない状態で、tofu initしてtofu applyするだけで移行完了です。tfstateや.terraform.lock.hclが書き換わります。
もしs3バックエンドを使っている場合は、Terraform v1.6以降でいくつか破壊的変更が入っているものが、OpenTofu v1.6以降にも実装されているので、OpenTofuへの移行のタイミングで同じ問題を踏む可能性があります。これは厳密にはTerraformとOpenTofuの非互換ではないのですが、移行のタイミングでバージョンを飛ばして移行すると踏む問題なので注意が必要です。
https://developer.hashicorp.com/terraform/language/v1.6.x/upgrade-guides#s3-backend
Terraform v1.5未満からのアップデートの場合は、tfstateのフォーマット的にはTerraform v0.14以降であれば一撃でアップデートできそうな気もしますが、Terraformのマイナーバージョン間でも若干の非互換はあるので、Terraform v1.5系の最後である1.5.7を一旦刻んだ方が無難だと思います。
tfstateは内部の実装詳細ですが、もし将来的に互換性のない変更が入ってもTerraformからOpenTofuへの移行はOpenTofu側で読み替えのルールを実装することで、最新のTerraformバージョンからの移行パスはサポートされると期待してよいでしょう。一方で、OpenTofuからTerraformへの戻しは、HashiCorpがOpenTofuを無視し続ける限りは困難で、移行直後であればtfstateのバックアップなどから戻せますが、移行してしばらくしてから戻そうとすると、全リソースをimportし直すしか正しい手段がなさそうです。まずは小さめのプロジェクトから実験的に試してみるのがよいかなと思います。
TerraformとOpenTofuの違い
TerraformからOpenTofuへの公式の移行ガイドは主に非互換な部分についての記載はあるものの、後方互換性のある新機能などについては言及がありません。OpenTofuの新機能について、この記事でも既にいくつか言及しましたが、ここではTerraformとOpenTofuの違いについて、機能面で整理してみます。
OpenTofuの公式ドキュメントは以下にあります。
https://opentofu.org/docs/
CLI
CLIとしてのterraformコマンドは、tofuコマンドにリネームされました。基本的な使い方はterraformコマンドと同じで、tofu init/plan/apply のように読み替えるだけで使えます。
バイナリがリネームされた影響で、3rd-partyのツールなどでterraformコマンドを内部的に呼び出しているものは、tofuコマンドに差し替えが必要です。
また標準出力やエラー出力でTerraformと表示されていた箇所が、OpenTofuにリネームされています。普通にユーザとして使う分には問題ないと思いますが、3rd-partyのツールで標準出力やエラー出力をパースしているようなものは、単にalias terraform=tofuで読み替えるだけでは意図した通りに動かない可能性があります。各ツールの対応状況を確認して下さい。
CLIの設定ファイルは .tofurc にリネームされていますが、後方互換性のため.terraformrcも引き続き利用可能です。
https://opentofu.org/docs/cli/config/config-file/#locations
tofu plan -concise
tofu側にしか生えていないオプションもいくつかあります。個人的に便利かなと思うのは、tofu plan -conciseで、plan出力のrefresh表示が抑止できるようになってます。あれいらんやろってみんな思ってたはず。
https://opentofu.org/docs/cli/commands/plan/#other-options
tofu validate -consolidate-warnings=false
ものすごく地味ですが、警告を省略せずに全件表示する tofu validate -consolidate-warnings=false フラグが生えています。たとえばプロバイダのリソース属性がdeprecatedになって警告を修正したいのに、警告がサマリされてしまい、修正箇所が全件特定できなくて困ったことはないでしょうか?という伝わる人にしか伝わらない、かゆいところに手が届くフラグです。
planと共通のオプションなので、planドキュメントのところに説明があります。
https://opentofu.org/docs/cli/commands/plan/#other-options
tofu apply -exclude
tofu apply -targetで特定のリソースだけピンポイントにapplyするという良い子は真似してはいけないハックが既にありますが、さらに意識の低いtofu apply -excludeというフラグが生えて、なんらかの理由で一部の差分だけを無視して残りをapplyすることができるようになりました。
これもplanと共通のオプションなので、planドキュメントのところに説明があります。
https://opentofu.org/docs/cli/commands/plan/#planning-options
ちなみに、このFeature RequestはTerraformのissueに10年前からあって、本稿執筆時点で1.5k以上+1されており、Terraform側のissueランキングで現在1位です。
https://github.com/hashicorp/terraform/issues/2253
Language
構文レベルでいくつか変更が入っている箇所があり、Terraformと相互運用しようとすると注意が必要です。
fork直後のTerraform v1.6とOpenTofu v1.6はほぼ同じですが、リリースサイクルは同じではないので、Terraform v1.7とOpenTofu v1.7のようにマイナーバージョン間で互換性があるという意味ではなく、マイナーバージョンと機能セットは一致しません。
.tofu拡張子
OpenTofu独自拡張の構文などは.tofu拡張子に分けて書くことができるようになりました。例えば同じファイル名で拡張子だけ異なるmain.tfとmain.tofuがある場合、main.tfは読み込まれず、main.tofuだけ読み込まれます。これによりファイル単位で上書きすることが可能です。ブロック単位でマージされるわけではなく、ファイル単位でどちらを読み込むという動作であることに注意して下さい。
https://opentofu.org/docs/language/files/
TerraformとOpenTofuで相互運用するような汎用モジュールを書いている人は、terraformブロックのrequired_versionだけでは機能セットを判断できませんが、.tfと.tofuファイルそれぞれにrequired_versionを書けばバージョン指定を区別できます。ちなみにterraformブロックに対応するopentofuブロックというのは今のところありません。
現時点で.tofu拡張子に対応しているツールは少ないですが、どんどんOpenTofuだけの独自拡張が増えていくと、明確に拡張子が分かれている方が扱いやすいとは思います。
removedブロック
Terraform v1.7に入ったremovedブロックは、OpenTofu v1.7にもありますが若干異なり、lifecycle destroy=falseの指定が不要です。
Terraformのremovedブロック:
https://developer.hashicorp.com/terraform/language/block/removed
OpenTofuのremovedブロック:
https://opentofu.org/docs/language/resources/syntax/#removing-resources
Terraformにremovedブロックが導入されたときに、なんでこんなめんどくさいことしたんだろなって思ってた人も多いと思いますが、removedブロック使いたいときにstateではなくresourceを削除したいことなんてないはずで、lifecycleブロックは冗長としか思えませんでした。OpenTofu v1.7は素直にlifecycleブロックをなくしてしまった結果、構文レベルで非互換ができてしまいました。
OpenTofu v1.10以降では、構文レベルでの互換性を維持するために、removedブロックにlifecycleブロックが追加されましたが、デフォルト値はdestroy=falseのままで、Terraformとデフォルト値が逆です。結局注意喚起のためにlifecycleブロックを省略した場合は警告が出るようになっており、めんどくせぇ。
removedブロック自体はapplyすれば削除しても構わないので、TerraformとOpenTofuで相互運用が必要なモジュールでなけば、TerraformからOpenTofuに移行する前に削除してしまってよいでしょう。
module source
Terraformはリソース属性を他のリソースの入力に使えたり、自由に変数参照ができて便利ですが、どこでも変数参照が使えるわけではありません。具体的にはTerraformの初期化に関する属性は変数参照できません。Terraformの実装は内部的にモジュールの読み込みフェーズとリソースグラフの構築フェーズに分かれており、前者のモジュールの読み込みフェーズでは変数参照ができませんでした。
OpenTofuでは、初期化のタイミングで静的に評価が可能な式に限定してこの制限を緩和し、variableとlocal変数が利用可能な場所がいくつか増えています。たとえばmoduleブロックのsource属性は変数が使えない場所でしたが、この仕組みでvariableとlocal変数が利用可能になってます。
https://opentofu.org/docs/language/modules/sources/#support-for-variable-and-local-evaluation
また、OpenTofuのOCI Registryサポートに伴い、module sourceで oci:// スキームが使えるようになっています。
https://opentofu.org/docs/language/modules/sources/#oci-distribution-repository
module variable / output
モジュールのvariableとoutputをdeprecatedとマークする構文が追加されました。
https://opentofu.org/docs/language/values/variables/#marking-variable-as-deprecated
https://opentofu.org/docs/language/values/outputs/#deprecated--marking-output-as-deprecated
Terraform側にもissueは立っていますが、まだ実装されておらず、汎用モジュールのTerraformとの互換性という意味では注意が必要です。
https://github.com/hashicorp/terraform/issues/18381
https://github.com/hashicorp/terraform/issues/5949
function
組み込み関数はTerraformとOpenTofuで随時追加されているので、使えるものと使えないものがあります。
OpenTofuでしか使えない関数は以下の通りです。
- base64gunzip
- cidrcontains
- urldecode
- tofu.applying
Terraformでしか使えない関数は、本稿執筆時点ではありませんでした。
組み込み関数の一覧もすぐに古くなりそうなので、公式ドキュメントへのリンクを張っておきます。Terraform / OpenTofu v1.6以降で追加された関数を使うときは注意しましょう。
Terraformの組み込み関数一覧:
https://developer.hashicorp.com/terraform/language/functions
OpenTofuの組み込み関数一覧:
https://opentofu.org/docs/language/functions/
ちなみにWeb上のドキュメントは一覧が見づらいので、一覧の差分比較したい場合は、ドキュメントのソースコードのファイル名のdiffを取った方が分かりやすいです。
https://github.com/hashicorp/web-unified-docs/tree/main/content/terraform/v1.14.x/docs/language/functions
https://github.com/opentofu/opentofu/tree/main/website/docs/language/functions
ただし例外として、以下は記載場所が異なっていました。
- terraform-applying.mdx: website/docs/language/expressions/references.mdx
- terraform-decode_tfvars.mdx: website/docs/language/providers/builtin.mdx
- terraform-encode_expr.mdx: website/docs/language/providers/builtin.mdx
- terraform-encode_tfvars.mdx: website/docs/language/providers/builtin.mdx
backend
Terraformではbackend設定に変数が書けず、Partial Configurationを使って設定を動的に差し替えるというテクニックがありましたが、OpenTofuではbackend設定にもvariableとlocal変数が利用可能になりました。module sourceの変数化などと同様に、初期化のタイミングで静的に評価が可能な式に限定されているので、リソース参照やデータソース参照などは書けません。
https://opentofu.org/docs/language/settings/backends/configuration/#variables-and-locals
State Encryption
OpenTofuはtfstateをクライアントサイドで暗号化する機能が追加されています。暗号鍵は単純なパスワードだけではなく、AWSやGCPのKMSなどを使うことも可能です。TerraformではAPIキーやパスワードなどのシークレットはsensitiveとマークすることで、標準出力上でマスクすることが可能でしたが、tfstateには平文が書かれてしまう問題がありました。この問題は、Ephemeral valuesとWrite-only attributesの導入で解決されつつありますが、プロバイダ側の対応が必要なので、tfstateをクライアントサイドで暗号化することは依然として有効な手段です。
https://opentofu.org/docs/language/state/encryption/
S3-native state locking
Terraform v1.10で導入された、s3バックエンドのDynamoDB不要のtfstateロック機能はOpenTofuにも実装されています。
https://opentofu.org/docs/language/settings/backends/s3/
さらにOpenTofuでは、ロックファイルにS3オブジェクトタグが設定できるようになっています。これの何が嬉しいかというと、tfstateを保存するS3バケットは通常バージョニングしているので、ロックファイルがplanのたびに作成/削除されるとバージョン履歴にゴミが溜まってしまいます。しかしながらS3のライフサイクルルールでは、ファイルパスのprefixマッチはできますが、suffixマッチができません。なので、このロックファイルの履歴だけピンポイントに削除するライフサイクルルールを書くには、オブジェクトがタグ付けされている必要があります。OpenTofuでは、lock_tags属性でロックファイルに任意のタグを付与できるようになっています。Terraform側にもissueを立ててありますが、まだ実装されていません。
https://github.com/hashicorp/terraform/issues/36445
provider for_each
providerをregionとかでfor_eachしたいよねというやつです。これも前述のbackendの変数化などと同じ作戦で、初期化のタイミングで静的に評価が可能な式に限定して制限を緩和し、providerの設定でvariableやlocal変数の参照ができるようになりました。providerのエイリアスを設定して、そのままmoduleにもproviderの参照を渡せるようになります。セキュリティやガバナンス系の設定は複数リージョンにまとめてapplyしたいことが多いので捗ります。
https://opentofu.org/docs/language/providers/configuration/#for_each-multiple-instances-of-a-provider-configuration
一応補足としてAWSプロバイダのregion属性にだけ関して言うと、AWSプロバイダv6でresourceレベルregion属性が実装されたので、provider for_eachを使わなくても、resource for_eachでregionを切り替えることは可能になっています。ただaccountは切り替えられないのと、AWSプロバイダ固有の機能なので、すべてのプロバイダで使える汎用的な仕組みではありません。
https://registry.terraform.io/providers/hashicorp/aws/latest/docs/guides/enhanced-region-support
Terraform側にもprovider for_eachのFeature Requestが長年あったのですが、HCP Terraform Stacksとして実装されてしまったので、実質的にTerraform単体では使えません。
https://github.com/hashicorp/terraform/issues/24476
lifecycle enabled
lifecycleブロックにenabled属性が追加され、リソースの有効化/無効化をより直感的に書けるようになりました。これまでcount属性を使って0/1でリソースの有効化/無効化を表現していたやつですが、より意図が明確になります。個人的には新しいことができるわけではないので、そこまで欲しいとは思ってなかったけれども、これも昔からTerraformにあるFeature Requestで意外と人気があります。
https://github.com/hashicorp/terraform/issues/21953
import identity
Terraform v1.12からimportブロックでidentity属性が追加されています。これは従来のid属性に一貫したネーミングルールがなく、自動化が困難という問題に対してプロバイダプロトコルレベルで新しく交通整理し直すためのものです。後述のList操作による一括importで必要となる部品です。この機能を使うにはプロバイダ側の対応が必要ですが、プロバイダプロトコルは共通なので、OpenTofuにもそのうち実装されると思いますが、本稿執筆時点ではまだ実装されていません。
https://developer.hashicorp.com/terraform/language/import
https://github.com/opentofu/opentofu/issues/2854
listブロック
Terraform v1.14からCRUDに足りていなかったList操作が追加され、listブロックを定義してterraform query -generate-config-out=でresourceブロックとimportブロックを自動生成し、一括インポートする機能が生えました。OpenTofuにもそのうち実装されると思いますが、本稿執筆時点ではまだ実装されていません。
https://developer.hashicorp.com/terraform/language/import/bulk
actionブロック
Terraform v1.14からactionブロックが追加されました。これは従来のprovisionerを置き換える何かですが、ライフサイクルにフックしてプロバイダ側でアクションを定義できるようになる仕組みです。provisionerは任意のコマンドが実行できるのでセキュリティ的に問題があったり、Terraformコアのビルトインなので拡張性が低かったりしましたが、プロバイダ側でユースケースに特化したアクションを実装できるようになりました。OpenTofuにもそのうち実装されると思いますが、本稿執筆時点ではまだ実装されていません。
https://developer.hashicorp.com/terraform/language/block/action
https://github.com/opentofu/opentofu/issues/3309
Registry
Terraform Registry (registry.terraform.io)に相当するのは、OpenTofu Registry (registry.opentofu.org)です。既存のtfファイルやtfstateをそのまま使えるように、Terraform Registryへの通信は、暗黙にOpenTofu Registryに捻じ曲げられています。
Webサイト上で検索やドキュメント参照などもできるようになってます。
https://search.opentofu.org/
OpenTofu Registryが建てられた時点でTerraform Registryに存在したProviderやModuleは一括で登録されており、バージョンアップも定期的にチェックして自動反映されているので、大体メジャーどころはカバーされていると思いますが、最近Terraform Registry側に新規登録されたものは、OpenTofu Registryには登録されていない可能性があります。
OpenTofu Registryの実体はCloudflareのCDNですが、メタデータは以下のリポジトリで管理されているので、自作ProviderやModuleなど欲しいものが登録されていない場合は、登録フローを読んでissueを立てると登録してもらえます。
https://github.com/opentofu/registry
provider
Terraform ProviderはライセンスがMPL2のまま配布されており、プロバイダのプロトコルの互換性が維持される限りは、OpenTofuでTerraform Providerがそのまま使えます。また将来的なプロトコル変更があっても、Terraform Plugin Frameworkや、gRPCのprotoファイルがMPL2のまま配布されている限りは、OpenTofuにも後追いで実装することは可能です。
Terraform Registryは実質GitHub Releaseへのリダイレクタなのですが、例外があり、HashiCorp管理の公式プロバイダは、GitHubではリリース物が配布されていないので、OpenTofuはforkして自前でソースからビルドし直しています。Goコンパイラのバージョンやコンパイルのオプションなども微妙に違いますが、これが機能レベルで問題になるケースはほとんどないとは思います。
HashiCorp管理の公式プロバイダは、required_providersにhashicorp/awsと書いても、opentofu/awsと書いても、OpenTofu Registryはgithub.com/opentofu/terraform-provider-awsのリリース物をダウンロードするので、どちらでも結果は同じですが、TerraformとOpenTofuのモジュールの互換性という意味では、hashicorp/awsと書いておいた方が無難かなと思います。
プロバイダの依存ロックファイルの名前は.terraform.lock.hclのままで、.tofu.lock.hclではありません。また、前述の通り、OpenTofu Registryのアドレスが registry.opentofu.org になっている点と、プロバイダはバイナリとしては別物なので、当然.terraform.lock.hclに記録されるハッシュ値も異なります。Terraformで作成した .terraform.lock.hcl は、移行時に削除しなくても、tofu initしたタイミングで勝手に書き換えてくれます。
またプロバイダをOCI Registryで配布する場合は、providerのブロックのsource属性に指定するのではなく、CLI設定ファイル(.tofurc)のprovider_installationブロックにoci_mirrorを指定する必要があります。これはプロバイダの論理的なアドレスと物理的なアドレスを区別している都合です。
https://opentofu.org/docs/cli/config/config-file/#explicit-installation-method-configuration
testフレームワーク
Terraform v1.6から追加されたterraform testコマンドに相当する、tofu testコマンドは実装されています。
https://opentofu.org/docs/cli/commands/test/
Terraformに追加されている機能は、随時OpenTofu にも実装されたりしているので、外部仕様は揃えようとしていますが、それぞれ独自に実装されているので、細かい挙動レベルの互換性はあまり期待し過ぎない方がよいのではないかと思っています。OpenTofuのみで使う分には問題ないと思いますが、Terraform / OpenTofu両方対応のモジュールのテストを書こうとするといろいろハマりそうな気はします。あえてTerratestなどの3rd-partyツールを使ったほうが、差分吸収レイヤとして同じテストを使いまわしできてよいかもしれません。
OpenTofuの周辺のエコシステム
OpenTofuの周辺のエコシステムは、現状まだまだ未発達です。
Terraform関連ツールのOpenTofuの対応状況は、awesome-opentofuを見るか、
https://github.com/virtualroot/awesome-opentofu
OpenTofuのGitHubのDiscussionに調査スレがあるので、このへんを参考にするとよいでしょう。
https://github.com/orgs/opentofu/discussions/1104
使ってるツールがOpenTofuに対応しているかは、そのツールのリポジトリのissueなどを見たほうが最新の状況が把握できて確実です。issueがあるが未対応なら+1しておき、issueがなければ立てておくとよいでしょう。メンテナの立場では、ユーザの需要がないとなかなか対応の優先度は上がりません。
すべてのツールを網羅することはできませんが、本稿執筆時点でハマりそうなポイントをいくつか書いておきます。
バージョン管理
Terraformのバージョンをtfenvで切り替えてた人も多いと思いますが、tfenvはOpenTofu対応しない方針です。
https://github.com/tfutils/tfenv/issues/409
結果としてTerraform/OpenTofu両方対応したtenvが爆誕しました。
https://github.com/tofuutils/tenv
私はasdf派なので、asdfのOpenTofu用のプラグインを使っています。
https://github.com/virtualroot/asdf-opentofu
Dependabotは package-ecosystem: "opentofu"で使えるようになってます。
https://docs.github.com/en/code-security/dependabot/working-with-dependabot/dependabot-options-reference#package-ecosystem-
Renovateはissueは立ってますが、まだ動きはありません。
https://github.com/renovatebot/renovate/issues/30500
tfupdateはv0.9.0からOpenTofuに対応しています。
環境変数 TFREGISTRY_BASE_URL=https://registry.opentofu.org/ をセットすることで、OpenTofu Registryを参照できるようにしてあります。
https://github.com/minamijoyo/tfupdate/pull/134
IDE
Terraformの公式VSCode拡張とLSPサーバはHashiCorpが開発していたので、OpenTofu対応は期待できません。
個人でforkしてメンテするのは重すぎるので、OpenTofuの公式VSCode拡張とLSPサーバができました。
https://github.com/opentofu/tofu-ls
https://github.com/opentofu/vscode-opentofu
あと流行りのMCPサーバも公開され、公式のリモートMCPサーバも提供されています。
https://github.com/opentofu/opentofu-mcp-server
IntelliJにもOpenTofu対応が入っています。HashiCorpが開発していないIDEは、普通にFeature Requestで需要があれば、そのうち対応してくれるのではないかと思います。
https://blog.jetbrains.com/idea/2024/11/intellij-idea-2024-3/#frameworks-and-technologies
Linter
tflintは内部実装でTerraformのコードを流用しており、OpenTofuをサポートしない方針です。
https://github.com/terraform-linters/tflint/issues/2037
OpenTofuはTerraformにない構文が追加されていたり、式の評価のセマンティクスが微妙に違うので、これもforkをメンテするのは重そうです。今のところtofu lintコマンドとしてコアに入れちゃうか、tofulintという別ツールとしてforkしちゃうかみたいな議論はあるものの方針は決まっていません。
https://github.com/opentofu/opentofu/issues/2213
需要はあると思うし、issueランキングの上位にも入っているので、そのうち何かしら動きがあるのではないかと思っています。
当面はOpenTofu独自拡張を使う場合は、.tofuファイルに分けてパースエラーにならないようにするなどの工夫が必要そうです。
CI/CD
HCP Terraform相当のSaaSは、OpenTofuの開発を支えているSpacelift、env0、Scalrあたりを使ってあげるとよいんじゃないでしょうか。Terragrunt派の人はそもそもHCP Terraform使ってないと思いますが、GruntworkがTerragrunt Scaleというのを作ってます。
OSSではAtlantis、tfactionなどは既にOpenTofu対応しています。DiggerはSaaS版とOSS版があり、どちらもOpenTofu対応しています。
あとtfmigrateをCI/CDに組み込んで使っている人もいると思いますが、環境変数 TFMIGRATE_EXEC_PATH=tofu をセットすることで、tofuコマンドが使えるようにしてあります。
ここで全部のツールを取り上げることはできませんが、各自自分の使ってるツールの対応状況を確認してみて下さい。
今後の展望
OpenTofuプロジェクトの現状を踏まえ、今後の展望についての個人的な見解を述べます。いろいろ推測を含むので、噂話レベルの期待値で読んで下さい。
IBMによるHashiCorpの買収の影響
OpenTofuプロジェクトのリスク要因として影響が見えていないのが、IBMによるHashiCorpの買収です。
2024年4月に買収が発表され、子会社ではなく吸収合併という形で2025年2月末に買収手続きが完了し、2025年9月から事業はIBMに引き継がれました。引き続きHashiCorpというブランドは残るものの、法人格としてのHashiCorpは消滅しました。
https://www.hashicorp.com/ja/blog/hashicorp-officially-joins-the-ibm-family
https://www.hashicorp.com/ja/blog/what-transition-to-ibm-means-hashicorp-customers-greater-value-same-commitment
買収後にMPL2に戻すというミラクルをひっそり期待していましたが、そのようなことは起きませんでした。
本稿執筆時点ではTerraformのライセンスの著作権表記はHashiCorp, Inc.のままになっていますが、そのうち変更されるでしょう。
ただもともとHashiCorp BSLの趣旨からして、条文が変更されるのではなく所有者がIBMになるだけであれば、実質的な解釈が大きく変わるということはないとは思います。
ところで、ちょうどこの記事を書いてる途中に、2つほどニュースがありました。
1つは、Terraform CDK(いわゆるcdktf)の開発終了とアーカイブのお知らせが出たのですが、この短いSunset Noticeで「HashiCorp, an IBM Company」が何度も出てくるのがちょっとだけ気になりました。なにか思うところがあったのでしょうか。もちろん意思決定者が変われば、まったく影響がないということもないのでしょう。
https://github.com/hashicorp/terraform-cdk
もう1つは、いつまで使えるか謎だったHCP Terraformのレガシーな5ユーザまで無料プランの廃止です。コスト構造は理解するけど、リソース数課金はコスト管理がしづらいのだよな。いつまでも、あると思うな、無料枠というやつです。
https://www.reddit.com/r/Terraform/comments/1pngkr4/hcp_terraform_free_is_ending_choose_a_new_plan/
OpenTofuの新機能
OpenTofuでは、今後のリリースのマイルストーンを公開していますが、本稿執筆時点ではv1.11がリリースされたばかりで、v1.12のマイルストーンはまだこれから検討という段階です。
https://github.com/opentofu/opentofu/milestones
OpenTofuの開発チームは、issueで+1が多いものを優先的に検討する方針なので、issueランキングを眺めて欲しい機能があれば、+1して投票しましょう。
個人的に気になっているものをいくつかピックアップして紹介します。本稿執筆時点のmainブランチはv1.12.0-alphaです。
lifecycle prevent_destroyでの変数参照
lifecycleブロックで変数参照を使いたいという提案がいろいろありますが、属性によって実装上の検討事項が違うので、属性ごとにissueが分かれています。prevent_destroyでの変数参照は既にmainブランチにマージされており、OpenTofu v1.12に入りそうです。
https://github.com/opentofu/opentofu/issues/2522
languageブロック
terraformブロックのrequired_versionは、TerraformのバージョンなのかOpenTofuのバージョンなのか?terraformブロックはopentofuブロックにリネームすべきではという話に関連して、そもそも現状terraformブロックに設定できる項目が混沌としているので、言語仕様に関する設定をまとめるlanguageブロックを導入する提案があり、OpenTofu v1.12マイルストーンになっています。
https://github.com/opentofu/opentofu/issues/3300
プロバイダプロトコルの拡張
OpenTofuに持ち込まれるFeature Requestにはプロバイダプロトコルを変更しないと実装できないものがあります。現状TerraformプロバイダプロトコルはHashiCorpが管理しており、OpenTofuが独自にプロトコル定義を変更してしまうとプロバイダの互換性が失われてしまいます。とはいえ、先送りしつづけてもどこかでこの問題と向き合う必要があるので、プロトコルの互換性を維持しながら、OpenTofu独自の拡張を加える方法が検討されています。
https://github.com/opentofu/opentofu/pull/3080
レジストリプロトコルの拡張
.terraform.lock.hclに記録されるh1ハッシュの値をローカルで計算せずにOpenTofu Registry側で事前に計算しておき、Registryから直接h1ハッシュを返す提案が検討されています。.terraform.lock.hclの管理が簡単になるので、個人的に期待しております。
https://github.com/opentofu/opentofu/pull/3434
Terraliths
HashiConf 2025でHCP Terraform StacksがGAしました。これは複数のrootモジュール間の依存を定義して一括でapplyできるTerragruntのような何かです。これはHCP Terraform(旧Terraform Cloud)の機能なので、Terraformを単体で使っている人は残念ながら利用できません。
https://developer.hashicorp.com/terraform/language/stacks
Terraform Stacksのオーケストレーション相当の機能は、OpenTofuとしては今のところTerragruntを使ってくれというスタンスのようです。
https://github.com/opentofu/opentofu/issues/931
TerragruntにはもともとStacksのような機能は以前からありましたが、Terragrunt v1.0に向けてStacksという新機能で概念を整理しなおしました。
https://github.com/gruntwork-io/terragrunt/issues/3313
余談ですが、Terragrunt自体は今のところTerraform v1.6以降も引き続きサポートしており、TerraformとOpenTofuの両方をサポートしているものの、Terragrunt v0.89.0+かつOpenTofu v1.10+であれば、プロバイダキャッシュでパフォーマンスが大幅に改善するなど、OpenTofu固有の最適化も入っています。
https://github.com/gruntwork-io/terragrunt/releases/tag/v0.89.0
OpenTofuとしてのStacksの別解として、そもそもrootモジュールを分割せずに巨大なモノリス(=Terraliths)を管理しやすくするという議論もあります。
tfstateのロックの粒度を細かくしたり、技術的に超えないといけない壁は高いですが、OpenTofuの将来的な方向性としては興味深いです。
https://github.com/opentofu/opentofu/issues/2860
Terraformの新機能
最後に、Terraform側で今後追加される機能についてもチラ見しておきましょう。本稿執筆時点のmainブランチはv1.15.0-alphaです。
Terraformはマイルストーンを公開していないので、Pull Requestなどを眺めて動きがありそうなものをピックアップしてます。
Deprecation Warning For Input/Output Variables
OpenTofuにはモジュールのvariableとoutputをdeprecatedとマークする構文が追加されていますが、Terraform側でも実装中です。
https://github.com/hashicorp/terraform/issues/18381
https://github.com/hashicorp/terraform/issues/5949
Pluggable State Store
tfstateを保存するbackendをプラグインとして切り出す構想です。backendはクラウドプロバイダごとに固有の実装が必要かつ認証ロジックなどはプロバイダ周りと二重メンテになるので、Terraformコアチームとしてはメンテナンス負荷が高く、切り出したい気持ちは分かります。
https://github.com/hashicorp/terraform-plugin-go/pull/563
対応するOpenTofu側のissueは以下です。
https://github.com/opentofu/opentofu/issues/382
Deferred Actions
実験的機能として、Terraform v1.9ぐらいからterraform plan -allow-deferralフラグがalphaビルドだけ生えています。当初これTerraform Stacks用の機能だと勘違いしてたのですが、countやfor_eachにunknown valuesを渡せるようにする実験のようです。なかなかstableに降ってこないので、詳細がよくわかっていません。
https://github.com/hashicorp/terraform/pull/34914
おわりに
この記事では、TerraformのOSS版のforkであるOpenTofuについて紹介し、OpenTofuの採用を検討しているTerraform職人が押さえておくべきポイントをまとめました。
Terraformで人気のFeature RequestはOpenTofu側にも提案が持ち込まれる流れが続いており、OpenTofuの開発チームもユーザ獲得のために積極的に取り込んでいます。純粋なOSSライセンスであることに興味がない人でも、欲しい機能があるならOpenTofuに移行するモチベーションになり得ます。
OpenTofu界隈は現在進行系でいろんな議論が並列で進んでおり、しばらく混沌としているとは思いますが、いきなりプロジェクトがなくなることは、さすがにもうなさそうな雰囲気です。Terraformの便利機能は随時取り込んで互換性を維持しつつ、ユーザ獲得のためにOpenTofu独自機能をいろいろ追加していけると、Infrastructure as Codeツールとして独自の地位を確立するのではないかと期待しています。
現時点では周辺のエコシステムが追いついてきてない感は否めませんが、まずはユーザが増えないとエコシステムは広がっていきません。多少人柱になってもよいぞという人は、とりあえず小さいプロジェクトからでも試してみて、みんなでオープンな選択肢を育てていきましょう。