Terraform職人のためのOpenTofu入門

この記事は [クラウドワークス Advent Calendar 2023](https://qiita.com/advent-calendar/2023/crowdworks) シリーズ1 の 4日目の記事です。

# はじめに

「父さんな、Terraform職人やめてお豆腐職人で食っていこうと思うんだ」と言いたいだけの [@minamijoyo](https://qiita.com/minamijoyo) です。

2023年8月HashiCorpはこれまでMPL2のOSSライセンスで公開していた主要製品をBSL(Business Source License)に変更することを発表し、Terraformはv1.6.0からOSSではなくなりました。
このライセンス変更を受けて、OSS版のTerraformを求める人たちで、MPL2時点のコードベースからforkしたOpenTofuの開発が進められています。
HashiCorpのBSLは、実質的に競合他社の商用利用に制限をかけたもので、ほとんどの一般的なユーザに直接的な追加の制限はありませんが、間接的にTerraformのエコシステムに与える影響は少なくありません。

筆者自身は、HashiCorpの競合でも、OpenTofuの競合でもない中立な立場ですが、長年Terraformの3rd-partyツールを書き散らかし、HashiCorpからCore Contributorとして表彰してもらうぐらいには、TerraformのOSSのエコシステムの発展に貢献してきました。
HashiCorpのライセンス変更は昨今の脱OSSの流れもあり、OSSタダ乗りの一般論として語られがちですが、少なくともTerraformに関して言えば、ここ数年コミュニティ側からの機能追加のPullRequestはほとんどまともにレビューしてもらえず、軽微なバグ修正ぐらいしか取り込んでもらえない状態が続いていました。タダ乗りしていると一方的に扉を閉ざす前に、もっとコミュニティに助けを求めて欲しかったな、というのが個人的なお気持ちです。

この記事では、Terraform職人が知っておくべきOpenTofuプロジェクトの概要と現在の状況について説明し、現時点で分かっているTerraformからの変更点などについて整理し、今後の展望についての個人的な見解を述べます。

本稿執筆時点のOpenTofuのバージョンはv1.6.0-beta1です。まだstableなリリースが出ていませんが、今のところリリース予定は12月中旬〜1月中旬頃とアナウンスされています。少なくともstableなリリースが出るまでは、今すぐOpenTofuに移行しようという人はほとんどいないと思いますが、そういえばOpenTofuってその後どうなったんだっけ？と気になっているTerraform職人の皆さんの参考になれば幸いです。

# OpenTofuプロジェクト

## 概要

OpenTofuはTerraformのBSLライセンス変更前のMPL2のコードベースからforkされた、OSSのインフラ構成管理ツールです。Linux Foundation傘下のプロジェクトとして、引き続きMPL2ライセンスで開発が進められています。

公式サイト: https://opentofu.org
リポジトリ: https://github.com/opentofu/opentofu

コミュニティベースのOSSプロジェクトですが、本稿執筆時点では、Steering CommitteeとしてGruntwork、Spacelift、env0、Scalr、Harnessの5社が中心となって開発を進めています。
Terraformのdrop-in replacementを謳っており、既存のTerraformのtfファイルやtfstateがそのまま使えます。Terraformからの変更点などについては後述します。

## 経緯

略歴というほどの歴史もまだないですが、記録としてプロジェクトの経緯などをまとめておきます。

### HashiCorpのライセンス変更

2023/08/10 HashiCorpはこれまでMPL2のOSSライセンスで公開していた主要製品をBSL(Business Source License)に変更することを発表しました。

https://www.hashicorp.com/blog/hashicorp-adopts-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://spdx.org/licenses/BUSL-1.1.html
https://spdx.org/licenses/BSL-1.0.html

発表当時、ライセンスの文言が非常に曖昧で、大きな混乱を生みました。というのも実質的に商用利用の条件である「Additional Use Grant」の記載が以下のとおりでした。

> You may make production use of the Licensed Work, provided such use does not include offering the Licensed Work to third parties on a hosted or embedded basis which is competitive with HashiCorp's products.

このhostedやembedded、competitiveとは具体的に何を意味するのでしょうか？
その後、FAQにいろいろ追記されましたが、

https://www.hashicorp.com/license-faq

当時の混乱の様子は、以下のコミュニティフォーラムのスレッドでも感じられます。

https://discuss.hashicorp.com/t/hashicorp-projects-changing-license-to-business-source-license-v1-1/57106

FAQの重要な部分に関しては、2023/10/17にライセンスの「Additional Use Grant」の部分を明確化する修正が反映されており、本稿執筆時点では以下の通りになっております。

[https://www.hashicorp.com/bsl](https://www.hashicorp.com/bsl)

> You may make production use of the Licensed Work, provided Your use does not include offering the Licensed Work to third parties on a hosted or embedded basis in order to compete with HashiCorp’s paid version(s) of the Licensed Work. For purposes of this license:
A “competitive offering” is a Product that is offered to third parties on a paid basis, including through paid support arrangements, that significantly overlaps with the capabilities of HashiCorp’s paid version(s) of the Licensed Work. If Your Product is not a competitive offering when You first make it generally available, it will not become a competitive offering later due to HashiCorp releasing a new version of the Licensed Work with additional capabilities. In addition, Products that are not provided on a paid basis are not competitive.
“Product” means software that is offered to end users to manage in their own environments or offered as a service on a hosted basis.
“Embedded” means including the source code or executable code from the Licensed Work in a competitive offering. “Embedded” also means packaging the competitive offering in such a way that the Licensed Work must be accessed or downloaded for the competitive offering to operate.
Hosting or using the Licensed Work(s) for internal purposes within an organization is not considered a competitive offering. HashiCorp considers your organization to include all of your affiliates under common control.
For binding interpretive guidance on using HashiCorp products under the Business Source License, please visit our FAQ.

Terraformのコンテキストに限定してざっくり言うと、Terraform Cloudの競合サービスには使わないでねという理解でよい認識ですが、私は法律の専門家ではないので、ライセンスの解釈については各自の責任で判断して下さい。（お約束）

### OpenTF Manifestoの公開

HashiCorpのライセンス変更の発表からほどなく、2023/08/14 Gruntwork、Spacelift、env0、Scalr、Digger、Massdriver、TerrateamなどTerraform関連ベンダの連合がOpenTF Manifestoという文章を公開しました。これはTerraformのライセンス変更に対する反対表明で、元のOSSライセンスに戻してくれなければforkするよという内容のものでした。

https://opentofu.org/manifesto
https://github.com/opentofu/manifesto

この宣言文章を置いただけのGitHubリポジトリが、本稿執筆時点で36.2k starsあり、コミュニティの関心の高さが伺えます。参考までに本家のTerraform本体のリポジトリである hashicorp/terraform は39.5k starsでした。

ライセンス変更の直接的な影響を受けるユーザは極めて少数であるにも関わらず、なぜこれほどまでの支持を受けているのでしょうか？TerraformがOSSとして維持されることがどれほど重要であるのかの論点は、以下のGruntworkのブログによくまとまっています。

https://blog.gruntwork.io/the-future-of-terraform-must-be-open-ab0b9ba65bca

文中で出てくる特に印象的な例を、ざっくり意訳すると以下のようなかんじでしょうか。

- あなたがCTOだとして、なぜわざわざリスクを冒してBSLのTerraformを選ぶのか？たぶんあなたは、将来の頭痛の種がない、OSSの代替ツールを選ぶだろう。
- あなたが法務担当だとして、開発者がBSLのツールを使いたいと言ってきたら？わざわざリスクを冒す理由がないので、たぶん禁止リストに入れるだろう。
- あなたが開発者だとして、なぜBSLのプロジェクトに貢献するのか？将来自分が使える保証もないのに。たぶん他の選択肢を探すだろう。
- あなたがDevOps関連のベンダだとして、なぜTerraformを選ぶのか？ある日HashiCorpがあなたを競合だと言ってくるかもしれないのに。たぶん他の選択肢を探すだろう。

Spacelift、env0、ScalrのようなガチのTerraform Cloudの競合とは異なり、TerragruntやTerratestを開発しているGruntworkが筆頭に立っているのは一見不思議かもしれません。GruntworkはTerraformの導入支援をしており、ある意味ではHashiCorpのパートナーです。最近日本語訳が出たオライリーの「詳解Terraform」の原書の著者は、Gruntworkの創業者で、これほどTerraformの普及に貢献してきた人はいないと言っても過言ではありません。しかしながら、Gruntworkのベストプラクティスを実践すると必然的にTerragruntに辿り着き、Terraform CloudはTerragruntをサポートしていないので、Terragruntが普及すればするほどTerraform Cloudにお金を落とすユーザが減ってしまいます。そういう意味では競合と言われるかもしれません。問題は競合かどうかを決めるのがHashiCorpで、その決定がいつでも覆せるのがビジネス上のリスクであると考えているようです。

ライセンス文言が曖昧であるという指摘のいくつかは、のちにFAQなどで補完されましたが、それでもHashiCorpが一方的にいつでも解釈を変更できるという事実は変わりません。Terraformをビジネスのコアとしていたベンダが、この上にビジネスを組み立てるのはあまりにもリスクが高すぎると判断するのは、構造上致し方ないところではあります。

もしTerraform CloudがOSSで、これをBSLにするという話であれば十分理解できますが、TerraformはサービスではなくCLIツールだし、もはやプログラミング言語だ、というのが彼らの主張です。もちろんOSSの開発にはお金がかかりますし、OSSにタダ乗りしているという指摘もありますが、HashiCorp自身もLinuxやGoなどの様々なOSSのエコシステムに依存しています。Terraformを含む多くのHashiCorp製品はGo言語で実装されています。もしGoogleが突然Go言語は競合他社は使わないでくれ、競合かどうかは我々が決めると言ったら何が起こるでしょうか？誰から見るかによってそれぞれに正義があるので、一概にどちらが正しいという単純な話でもないように思います。結局全部不況が悪いんや〜。

### Terraform Registryの利用規約変更

Terraformのプロバイダやモジュールを配布しているTerraform Registryの利用規約も変更され、Terraform関連以外では使わないでねという旨の文言が追記されました。

https://registry.terraform.io/terms

> You may download providers, modules, policy libraries and/or other Services or Content from this website solely for use with, or in support of, HashiCorp Terraform. You may download or copy the Content (and other items displayed on the Services for download) for personal non-commercial use only, provided that you maintain all copyright and other notices contained in such Content. You shall not store any significant portion of any Content in any form.

今見ると最終更新日が2023/08/24になっていますが、この変更が発見された当時2023/08/31時点では、最終更新日が2020/04/16のまま、インターネットのアーカイブに残っていた2022/12/20時点にはなかった文言が追加されており、こっそり利用規約が変わっているぞとOpenTF界隈がざわざわしていました。

https://github.com/opentofu/roadmap/issues/24

OpenTofuのstableリリースへのメインブロッカーがこのRegistry問題だったので、的確に初手痛いところを塞いできたなというかんじですが、まぁstableリリースが出た後に気づくよりも、長期的に見ればよかったのではないかと思います。

### OpenTFとしてforkを公開

OpenTF側が期限として定めた2023/08/25の時点でHashiCorpから回答がもらえなかったので、forkする方針だけ決定されましたが、この時点ではTerraform⇒OpenTFへのリネーム作業やコミュニティガイドライン整備のためにしばらくリポジトリは非公開のままでした。ちなみにコミットの履歴を見れば分かりますが、2023/08/25にforkする方針が発表されましたが、実際にはそれ以前からforkしてリネーム作業は開始していたようです。OpenTFなのにリポジトリがprivateとはこれ如何にという状態がしばらく続きましたが、2023/09/05にリポジトリが公開されました。

HashiCorpがライセンス変更を発表した時点でのTerraformのstableなリリースはv1.5.5だったので、v1.5.5からforkしたと思ってる人もいるかもしれませんが、実際にはライセンス変更がされる直前のmainブランチのコミットからforkされており、Terraform v1.6.0-alpha相当からforkされています。

https://github.com/hashicorp/terraform/commit/8a085b427b74ce3829500a59508b77465f1bbef0

またTerraform v1.5系のブランチはその後もMPL2のまま維持されており、本稿執筆時点ではv1.5.7はMPL2のまま配布されています。v1.5系がいつまで維持されるのかは定かではないですが、少なくとも次のv1.7が出るまではメンテされるとは思います。

### Linux Foundationに参加 ＆ OpenTofuにリネーム

このプロジェクトは当初OpenTFという名前でしたが、「TF」という文字列だけでも商標侵害リスクがあるとの懸念が出てきて、コミュニティで新しい名前を募集したところ、「tofuでいいんじゃない。略したらtfだし、terraformとも響きが違う」というネタなのか本気なのか分からない意見が圧倒的な支持を得て、2023/09/20 Linux Foundation傘下に入るタイミングでOpenTofuへリネームされました。

https://github.com/opentofu/opentofu/issues/296

ところで、豆腐って英語でもtofuなんですね。OpenTofuの公式ロゴはどうみても厚揚げですが、厚揚げは英語で「deep-fried thick tofu」とか「thick fried tofu」と言うそうで、thickを忘れると油揚げになるので注意が必要です。以上、どうでもいい豆知識でした。（豆腐だけに）

### 暫定のRegistryが完成＆最初のv1.6.0-alpha1リリースを公開

Terraform Registryは実質的にほぼほぼGitHub Releaseへのプロキシなので、急遽暫定のOpenTofu Registryが立てられました。ほとんどの3rd-partyのプロバイダはこれで問題ないですが、HashiCorp管理の公式プロバイダは、HashiCorpのリリースサーバから配布されており、GitHubではリリース物が配布されていません。ただプロバイダのソースはMPL2のままだったので、プロバイダのリポジトリもforkし、力技で過去バージョンも含め全部ソースからビルドし直されました。

たとえば、hashicorp/awsプロバイダは

https://github.com/hashicorp/terraform-provider-aws

以下のopentofu/awsプロバイダにforkされています。

https://github.com/opentofu/terraform-provider-aws

また、OpenTofuの実装側で、registry.terraform.io へのアクセスは、暗黙にregistry.opentofu.org に読み替えることで、Terraform Registryではなく、OpenTofu Registryと通信するようになっています。

2023/10/04 暫定のRegistryが完成し、最初のv1.6.0-alpha1のリリースが切られました。

### 安定版のRegistry設計としてHomebrew風の案を採用

alphaリリースのために暫定のRegistryが立てられましたが、stableなリリースに向けて、Registryが再設計されました。

ところでOpenTofuの開発チームは元々Terraform Cloudの競合サービスを開発しており、お互いはライバル同士でもあります。特定の1社が強い権限を持ちすぎないように、プロジェクトの運営には一定のガバナンスが必要です。重要な設計上の変更には、事前にRFC(Request For Comments)という公開設計レビューを行い、最終的にSteering Committeeにより判断するというプロセスを導入しています。

安定版のRegistryの設計では、3つのRFCが提案され、2023/11/02 そのうちの1つのHomebrew風の案が採用されました。

https://github.com/opentofu/opentofu/issues/741

これはプロバイダやモジュールのメタデータをGitHubのPullRequestベースで管理し、Homebrewがやってるように可能な限りバージョンアップを自動化する作戦です。この方式が採用された一番の理由は、RegistryのAPIサーバにRDBのような状態を持ったコンポーネントが不要で、ほぼCDNによる静的コンテンツ配信だけで実装できるので、高い可用性を維持しつつ、コアチームの運用負担が少ないからとのこと。

一方、新しいプロバイダやモジュールを登録するのにPullRequestが必要になってしまいますが、プロバイダやモジュールのメンテナがOpenTofuユーザではないケースも考慮すると、メンテナ以外の人でもメタデータを登録できるのは合理的な気もしています。Homebrewもツールの作者でない人が勝手に登録してますし、チェックサムや署名鍵などGitHubのリリースを参照するだけでメタデータの登録内容の妥当性が検証できるのであれば、登録する人が誰かを検証する必要はありません。

### v1.6.0-beta1のリリース＆安定版のRegistryに切り替え

本稿執筆中2023/11/30にv1.6.0-beta1がリリースされ、2023/12/01 安定版のRegistryに切り替えされました。
まだ正式な運用やワークフローなどはよくわかっていませんが、以下のリポジトリでメタデータを管理しています。

https://github.com/opentofu/registry

見たところ既に大量のProviderとModuleが登録されており、Terraform Registryに登録されていたものを、機械的に一括登録したようです。

ちなみに registry.opentofu.org のHTTPヘッダを見るとCDNにCloudflareを使ってるのが分かりますが、Cloudflareがスポンサーをしてくれてるとのこと。

### (v1.6.0のstableリリース予定)

本稿執筆時点では、v1.6.0のstableリリース予定は2023/12月中旬〜2024/1月中旬頃とアナウンスされています。 メインブロッカーだった安定版のRegistryが公開されたので、これから本格的にテストフェーズに移行する予定です。今のところ、これ以上大きく方針がブレることはなさそうに思います。

# Terraformからの変更点

本稿執筆時点でまだstableなリリースは出ていませんが、現状見えている範囲でTerraformからの変更点をまとめます。

## terraformコマンド ⇒ tofuコマンド

CLIとしてのterraformコマンドは、tofuコマンドにリネームされました。基本的な使い方はterraformコマンドと同じで、tofu init/plan/apply のように読み替えるだけで使えます。

バイナリがリネームされた影響で、3rd-partyのツールなどでterraformコマンドを内部的に呼び出しているものは、tofuコマンドに差し替えが必要です。例えば私がメンテしているtfmigrateでは、v0.3.19以降で環境変数 `TFMIGRATE_EXEC_PATH=tofu` をセットすることで、tofuコマンドが使えるようになっています。

https://github.com/minamijoyo/tfmigrate/pull/164

それぞれのツールの対応状況は、各ツールのリポジトリのissueなどを探してみて下さい。

## 標準出力やエラー出力のTerraform ⇒ OpenTofuへのリネーム

標準出力やエラー出力でTerraformと表示されていた箇所が、OpenTofuにリネームされています。

```bash
$ tofu version
OpenTofu v1.6.0-beta1
on darwin_arm64
```

普通にユーザとして使う分には問題ないと思いますが、3rd-partyのツールで標準出力やエラー出力をパースしているようなものは、単にalias terraform=tofuで読み替えるだけでは意図した通りに動かない可能性があります。こちらも各ツールの対応状況を確認して下さい。

あと当然ですが、fork後に追加されたエラーメッセージなどは異なるので、Terraform ⇒ OpenTofuへのリネーム以外の差分もあります。

## バージョン番号

OpenTofuはTerraformのv1.6.0-alpha相当からforkされたので、最初のstableなリリースはv1.6.0になる予定です。また、Terraform v1.6.0の新機能であるtestコマンドやs3バックエンドの変更なども取り込まれる予定です。
ライセンスの問題でTerraformのソースコードはコピペできませんが、Terraformに追加された機能については後追いで実装し、外部仕様レベルで互換性を維持する方針のようです。fork直後のv1.6は、ほぼほぼ互換と思ってよいかもですが、とはいえ今後もソースを流用せずにどこまで互換性が実現可能なのかというのは、現時点では不透明です。
仮にTerraformの後追いでマイナーバージョンのバージョニングを揃えていく方針でも、OpenTofu側で破壊的な変更が必要になった際に、Terraformのリリースサイクルに引きづられてしまうので、マイナーバージョンを揃えていく作戦も、いずれにせよそのうち破綻しそうな気はしてます。

## Registry

前述の通り Terraform Registry (registry.terraform.io) は利用規約でTerraform以外では使えなくなったので、OpenTofu用に OpenTofu Registry (registry.opentofu.org) が立てられました。既存のtfファイルやtfstateをそのまま使えるように、Terraform Registryへの通信は、暗黙にOpenTofu Registryに捻じ曲げられています。

Registryに登録されていないプロバイダやモジュールは使えませんが、OpenTofu Registry構築時点でTerraform Registryに登録されていたプロバイダやモジュールは、機械的に一括登録してあるので、既存のTerraformの依存はそのまま使えそうです。今後新規に登録されるものについては差分が発生しそうですが、Homebrew風のRegistryを採用することで、メンテナ以外でもPullRequestベースで登録してもらうことは可能です。

またOpenTofu Registryは今のところAPI専用で、プロバイダやモジュールなどのドキュメント用のWebサイトがありません。これは実装の優先度が低いだけで、そのうちドキュメントもWebサイト上で見れるようにするつもりはあるようです。

あとものすごい細かいですが、OpenTofu RegistryのProtocolは、Terraform Registryから若干の変更が入っています。具体的には、モジュールをダウンロード先を返すのに、Terraform RegistryはX-Terraform-GetというHTTPレスポンスヘッダを使っていますが、OpenTofu RegistryはHTTPレスポンスボディを使っています。これは静的コンテンツ配信に寄せるための意図的な仕様変更です。互換性を維持するために、tofuコマンドは、レスポンスボディがない場合は従来どおりヘッダにフォールバックすることで、Terraform Registry ProtocolをしゃべるPrivateなRegistryとも通信できるようにはなっています。逆にTerraformがOpenTofu Registryと通信できないことは実用上問題ないと思いますが、3rd-partyのツールで、Terraform Registryと通信するものは、OpenTofu Registry Protocolが完全に同じものではないので、互換性の問題が出てくるかもしれません。

https://github.com/opentofu/opentofu/issues/900

## Provider

Terraform ProviderはライセンスがMPL2のまま配布されており、プロバイダのプロトコルの互換性が維持される限りは、OpenTofuでTerraform Providerがそのまま使えます。また将来的なプロトコル変更があっても、Terraform Plugin Frameworkや、gRPCのprotoファイルもMPL2のまま配布されている限りは通信できるはずです。

前述のとおり、Hashicorp管理の公式プロバイダは、GitHubではリリース物が配布されていないので、OpenTofuはforkして自前でソースからビルドし直しています。Goコンパイラのバージョンやコンパイルのオプションなども微妙に違いますが、これが機能レベルで問題になるケースはほとんどないとは思います。

## .terraform.lock.hcl

依存のロックファイルの名前は.terraform.lock.hclのままで、.tofu.lock.hclではありません。また、前述の通り、OpenTofu Registryのアドレスが registry.opentofu.org になっている点と、プロバイダはバイナリとしては別物なので、当然.terraform.lock.hclに記録されるハッシュ値も異なります。手元で試したところ、Terraformで作成した .terraform.lock.hcl は、移行時に削除しなくても、tofu initしたタイミングで勝手に書き換えてくれます。

## Module

Terraformでv1.5で作成したtfファイルはそのまま利用可能です。ファイルの拡張子も.tfのままで、.tofuではありません。Terraform v1.6でもtfファイルのシンタックスに大きな変更はなく、組み込みスキーマであるs3バックエンドの変更も取り込まれています。

HCLライブラリはMPL2のまま配布されており、HCLレベルの変更はそのまま取り込まれるはずです。細かいバグ修正が同じパッチバージョンに入る保証はないですが、ほとんどエッジケースでしょう。

ただ将来的にOpenTofuにしか存在しない構文、またはその逆が出てきた場合に互換性の問題が出てくることは容易に想像が付きます。特にモジュールのrequired_versionを暗黙にTerraformとOpenTofuのバージョン番号に互換性があるかのように解釈してますが、論理的には別物です。このあたりのバージョニングをどうしていくつもりなのかは現状不透明です。共有Moduleをメンテしている人は、さしあたり最大公約数であるv1.5までのサブセットしか使わない方が無難でしょう。

## tfstate

Terraform v1.6でtfstateのフォーマットは変わっていないので、Terraformで作成したtfstateをそのままOpenTofuで利用可能です。

tfstateにはTerraform Registryのアドレスも含まれますが、Terraformで作成したtfstateはそのまま読み込んでtofu applyすると、勝手に読み替えてRegistryのアドレスが `registry.terraform.io/hashicorp/null` ⇒ 
 `registry.opentofu.org/hashicorp/null` のように自動で変換されます。ちなみに変換後のnamespaceは、 `opentofu/null` ではなく `hashicorp/null` になっていました。

またtfstateには最後にapplyしたterraform_versionも記録されていますが、試したところTerraform v1.6.5で作成したtfstateをOpenTofu v1.6.0-beta1で読み込んでtofu applyすると、tfstate内のterraform_versionはv1.6.0になっていました。フォーマットに互換性があれば、Terraformの方がバージョン番号が進んでいても移行できそうです。

tfstateは内部の実装詳細ですが、もし将来的に互換性のない変更が入ってもTerraform ⇒ OpenTofuへの移行はOpenTofu側で読み替えのルールを実装することで、特定のTerraformバージョンからの移行パスはサポートされるのではないかと思ってます。一方で、OpenTofu ⇒ Terraformへの戻しは、HashiCorpがOpenTofuを無視し続ける限りはリスクが高そうです。このあたりのtfstateの互換性の問題は、バージョンが離れるほど問題になりそうですが、OpenTofu陣営としては、Terraformからのスムーズな移行は最優先事項だと思うので、今後移行ガイドなどが整備されていくでしょう。

## Terraform Cloud

cloudブロックとremoteブロックのホスト名のデフォルトがapp.terraform.ioになっていたのが、暗黙のデフォルト値を削除し、必須項目になりました。同様にtofu login / logoutコマンドのホスト名も必須になりました。

Terraform CloudでOpenTofuを使いたい人はいないとは思いますが、Terraform Cloud互換の代替サービスでは引き続き利用可能です。

## testフレームワーク

Terraform v1.6の目玉機能であるterraform testコマンドに対応する、tofu testコマンドが実装されています。これはTerraform v1.6.0-alphaからforkした時点で途中まで実装されていたものですが、最終的な仕上げはそれぞれのプロジェクトで行われました。経緯からして機能差異がある可能性がありますが、ちょっと細かく精査できていません。いずれにせよTerraform v1.6以降の機能については、同等の機能があっても過度に互換性を期待しない方がよいとは思います。

## その他細かいバグ

ソースコードレベルでコピペできないので、その他細かいバグは直ってたり直ってなかったりします。バグもそれぞれのプロジェクトで報告ベースで修正されるので、そもそも報告されなかったものは修正されることもありません。drop-in replacementとは言っても、「一般的なユースケースの範囲で、tfファイルとtfstateがそのままOpenTofuでも動く」ぐらいの理解が現実的だと思います。

# 今後の展望

OpenTofuプロジェクトの現状を踏まえ、今後の展望についての個人的な見解を述べます。いろいろ推測を含むので、噂話レベルの期待値で読んで下さい。

## CNCFへの参加

OpenTofuプロジェクトがLinux Foundation傘下に入った狙いは、もちろん正統性を主張するための権威付けもあるとは思いますが、真の狙いはCNCF(Cloud Native Computing Foundation)を味方につけることだと解釈してます。コンテナ技術やKubernetes関連のエコシステムであるCNCFも、組織構造的にはLinux Foundation傘下で、AWS、Google、Microsoftなど主要なクラウドベンダが名を連ねています。現在のところTerraformプロバイダのライセンスは引き続きMPL2で開発されていますが、これがいつまで続くかは不透明ですし、Terraformが便利なのは豊富なプロバイダのエコシステムに支えられているので、クラウドベンダとのコミュニケーションのチャンネルは確保しておきたいところです。

Terraformのライセンス変更はクラウドコンピューティングのSPOF (Single Point Of Failure) となっており、突然のライセンス変更は新しいサプライチェーンのリスクです。Linux Foundationとしても昨今の脱OSSの流れに対して、我々はいつでもforkできるぞというメッセージが必要です。かくして両者の思惑が一致したわけです。

本稿執筆時点では、まだOpenTofuはCNCFには正式に加盟していませんが、なぜか来年2024年3月に開催されるKubeCon + CloudNativeCon EuropeにOpenTofu Dayというイベントが企画されているのを観測しており、これはもう実質内定と言ってもよいんじゃないでしょうか。

https://events.linuxfoundation.org/kubecon-cloudnativecon-europe/co-located-events/opentofu-day/

## OSSプロジェクトでの採用拡大

HashiCorpのBSLは、実質的に競合他社の商用利用に制限をかけたもので、ほとんどの一般的なユーザに直接的な追加の制限はなく、ほとんどのTerraformユーザはOSSであるかどうかを気にしていないかもしれません。一方でOSSのプロジェクトは、ソフトウェアのライセンスに敏感で、OSSでないものへの依存を排除する方針のプロジェクトもあります。

たとえばHomebrewはHashiCorp製品の登録を廃止し、Terraformへの依存をOpenTofuに切り替える方針で話が進んでいます。

https://github.com/Homebrew/homebrew-core/pull/139538

CNCFでもHashiCorpのライセンス変更の影響を受けるコンポーネントの調査が進められています。

https://github.com/cncf/foundation/issues/617

このようにユーザが直接望まなくても、OSSのコンポーネントして組み込まれるデフォルトの選択肢として、OpenTofu採用は緩やかに拡大していくでしょう。

## ライブラリ化

OpenTofuのManifestoには、プロジェクトの開発方針として、以下の5つが挙げられています。

https://opentofu.org/manifesto

- Truly open source: under a well-known and widely-accepted license that companies can trust, that won't suddenly change in the future, and isn't subject to the whims of a single vendor
- Community-driven: so that the community governs the project for the community, where pull requests are regularly reviewed and accepted on their merit
- Impartial: so that valuable features and fixes are accepted based on their value to the community, regardless of their impact on any particular vendor
- Layered and modular: with a programmer-friendly project structure to encourage building on top, enabling a new vibrant ecosystem of tools and integrations
- Backwards-compatible: so that the existing code can drive value for years to come

この中で、「Layered and modular」の部分に関しては、他とちょっと毛色が違うので、コンテキストを補足しておくべきかなと思います。

Terraformはv0.15.4以降、ほとんどすべてのGoパッケージをinternal/ディレクトリ配下に移動し、ライブラリとして外部からimportすることを禁止しました。internal/というディレクトリ名は、単なる慣習ではなくGoコンパイラレベルで外部からimportができなくなります。これによりTerraformの内部実装をimportして再利用していた3rd-partyのツールの多くが、最新版のTerraform v1.x以降に追従していくことが困難になりました。

https://github.com/hashicorp/terraform/pull/28723

一方、OpenTofuの開発チームは元々Terraform関連の周辺ツールやサービスを開発していた人たちなので、OpenTofuのライブラリ化には前向きです。今すぐというかんじでは全然ないとは思いますが、長期的には周辺の3rd-partyツールのエコシステムが発展しやすい土壌ができるでしょう。

https://github.com/opentofu/opentofu/issues/401

https://github.com/opentofu/opentofu/issues/758

https://github.com/opentofu/opentofu/issues/810

## OpenTofuの新機能

Terraformはライセンス変更される前から、ここ数年は基本的に設計レベルの変更はコミュティからは受け付けておらず、取り込まれるパッチはバグ修正などの軽微なものに限られていました。また設計ドキュメントが非公開で、実装だけPullRequestでシュッと出てくるので、コミュニティから大きめの機能を入れるのは実質的に不可能な状態でした。TerraformがOSSではなくなったことで、外部からのコントリビューションのモチベーションはさらに下がるでしょう。

一方で、OpenTofuはRFCという形で、設計変更を提案できるようにする方針で、長年Terraformで放置されていたissueが掘り起こされて、OpenTofu側で再度議論されています。例えばtfstateの暗号化は、Terraformでは2016年から提案されていますが、未だに実装されていません。

https://github.com/hashicorp/terraform/issues/9556

これについて、OpenTofu側でも再度議論されており、TerraformにPullRequestを取り込んでもらえなかったコントリビューターの人が、OpenTofu側にもPullRequestを送っており、OpenTofuのコアチームは導入に前向きなようです。

https://github.com/opentofu/opentofu/issues/297

またRegistryの設計と合わせて、ProviderやModuleの保存先として、OCI Registryに保存できるようにしようという提案もされています。OCI Registryは元々Docker HubやGitHub Container Registryのようなコンテナイメージの置き場を標準化したものですが、現在ではコンテナに限らずアプリケーションのライブラリなど汎用的なファイル置き場としての活用が進めらています。privateなProviderやModuleを保存するのに、自前でPrivate Terraform Registryをホスティングするのはオーバーヘッドが大きいので、GitHub Container RegistryのようなOCI Registryに保存できるようになると便利そうです。

https://github.com/opentofu/opentofu/issues/308

これに合わせてProviderの署名も現在はGPG鍵で署名していますが、Sigstoreを使ったキーレス署名を使えないかという検討もされています。

https://github.com/opentofu/opentofu/issues/307

Terraformはそこそこ歴史のあるソフトウェアなので、どうしても設計が古い箇所があるのは否めません。このように新しい視点で技術スタックの見直しが行われるのはよい機会だと思います。

OpenTofu v1.6.0のstableなリリースが出るまでは一旦新機能は入れない方針になっており、ほとんどの議論はpending-decisionのステータスになっていますが、stableなリリースが出た後は、積極的に議論が進むでしょう。上記は一例であり、まだ採用されるかどうかは未定です。ここで言いたいことは、これらの機能が採用されるかどうかではなく、議論の参加者や意思決定者が異なるので、結果的にOpenTofuはTerraformと異なる機能を持っていくことになるということです。

ほとんどの一般的なユーザにとって、ライセンスが純粋なOSSであるかどうかは興味がないかもしれません。結局のところ、自分の欲しい機能がTerraformとOpenTofuのどちらにあるのか？がツール選定のポイントになってくるとすると、差別化要因として、新機能は積極的に取り込まれていくでしょう。

OpenTofuプロジェクトは、Terraformのライセンス変更で死活問題な各社が協力して手を取り合って開発を進めており、向こう5年先まで18人分のフルタイムエンジニアの開発リソースをコミットしているので、会社が潰れない限りは開発が止まるとは考えづらいです。Terraformのコアチームは5人ぐらいなので、人数ベースでは勝ってますが、既存のコードベースに知見のない人たちで勝てるのかというのは疑問が残ります。これについては、私は短期的には悲観的ですが、長期的には楽観的です。既存のコードベースに対する正しい理解がなく、間違った設計判断をすることもあるとは思いますが、失敗しながら学んでいくでしょう。コミュニティからのコントリビューションの敷居も下がるので、多少不安定でもコミュニティの規模が拡大すれば、マンパワーで押し切るのではないかと思ってます。逆に保守的で完璧な設計よりも、9割のユースケースでうまくいくなら新機能をどんどん取り込んでスピード重視の方が、進化を加速し、ユーザの支持を獲得していくかもしれません。そうなったときにOpenTofuはOSS版のTerraformのforkではなく、独自のInfrastructure as Codeツールとして、Terraformとの互換性を切り捨て、別の道を歩むのかもしれません。

## Terraformの新機能

Terraform側で今後追加される機能についてもチラ見しておきましょう。現在のmainブランチはv1.7.0-alphaで、既にマージされてv1.7に入ることが見えているものは、terraform testコマンドの改善とremovedブロックです。その他、v1.7に入るのかは不明ですが、2023年10月に行われたHashiConf 2023では、今後のロードマップとして、Custom provider functions(プロバイダ特化の組み込み関数)やStacks (複数のモジュールをまとめてデプロイするTerragruntのような何か)などの話題が出ていました。

OpenTofuはTerraformのdrop-in replacementを謳っているので、Terraform側に追加された機能は後追いで追加する方針です。Terraformのソースコードを流用せずに外部仕様のみ模倣するのがどれぐらい現実的なのかは不明ですが、forkされたv1.6以降の機能は、完全に同じものと言うよりも、似たような何かと思って付き合うのが無難でしょう。

保守的な人は、しばらくTerraform v1.5の範囲にとどまって、様子見するのが無難ですが、Terraform v1.6やv1.7などからOpenTofuへの移行パスは用意されると思うので、現時点でTerraformの最新版へのバージョンアップを保留する必然性はあるようには思えません。ただ将来的に移行を考えているなら、v1.6以上の機能に依存するのは慎重にすべきでしょう。

# おわりに

この記事では、TerraformのOSS版のforkであるOpenTofuについて紹介しました。

OpenTofu界隈はしばらく混沌としているとは思いますが、Terraformはv1.xが出てからよい意味で安定的で退屈かもしれません。多少人柱になってもよいぞという人は、OpenTofuも選択肢の一つとして検討してみてはいかがでしょうか。

# 2024/12/02追記
改訂版を書きましたので、こちらもどうぞ↓

https://qiita.com/minamijoyo/items/2738b9ad5f6754b68400