背景
terraformではmavenやrubygemsなどと同様のバージョン制約構文が使えます。
モジュールやproviderのバージョンはこの構文により柔軟なバージョン指定ができます。
Renovateはこのバージョン指定を解釈して柔軟にバージョンアップのPRを作ってくれます(偉い!)。
具体的には
-
~> X.Yという書き方の場合はその範囲内で最新バージョンにするPRと、 メジャーバージョン(X部分)を上げるPRを別で作成 -
>= X.Yという書き方の場合はメジャーバージョンアップとマイナーバージョンアップも区別せずPRを作成
といった器用なことをしてくれます(そもそもの ~> と >= の挙動の違いについてはこちらを参照)。
このRenovateにGitHub Actionsによる terraform plan 自動実行などを組み合わせるとバージョンアップがほぼ自動になるため非常に便利です。
課題
RenovateとGitHub Actionsによりモジュールとプロバイダーの自動バージョンアップを使う前提の場合、どのようにバージョン指定を書くべきでしょうか。
2023/07/10追記
数ヶ月前、renovate botはバージョン指定が >= などでも .terraform.lock.hcl を更新してくれるようになりました。
なので、今では以下の = や ~> ではなく >= を使うべきです。 renovatebotの改良に感謝!
提案
- モジュールは
= X.Y.ZまたはX.Y.Z1 - プロバイダは
~> X.Y
で書きましょう。
モジュール を = で書くべき理由
「【Terraform】moduleのアンチパターンとそれに対するベストプラクティス5選」の「アンチパターン5. モジュールのバージョンを最低バージョンで指定してしまう」が理由です。
ちなみにこれを普通にやるとバージョンアップが煩雑になるのですが、renovateによりそこも自動化されるためこのプラクティスが非常に実践しやすくなります。
プロバイダ を ~> で書く意味
プロバイダはモジュールと違いロックファイルが今ではありますので = で指定する必要はありません。
なので >= と ~> の比較になりますが、 ~> が良いと思います。
terraformは概ねsemantic versioningを推奨しています(moduleのバージョニングで推奨している例)。そのためterraform本体やprovider自体もsemantic versioningベースのものがほとんどです。
そのため、 バージョンX.Y.ZのX部分が変わるときはプロバイダに非互換の変更が入るときです。
もし >= の方式で書いていた場合、 terraform init -upgrade でプロバイダをアップグレードすると互換性のないプロバイダにアップグレードされて terraform plan が壊れる可能性があります。
まだroot moduleでの宣言ならば良いですが、これを配布しているchild moduleのrequired_versionなどで書いてしまうとそれを参照しているすべてのroot moduleでも問題が発生します。
意味論的にも >= は互換性が壊れる可能性のある未来のメジャーバージョンアップ後も動作大丈夫ですよ、という意味になり辻褄が合いません。
~> の方式で書いた場合、メジャーバージョンアップの際にversion.tfファイルの書き換えが必要になってバージョンキャッチアップが先延ばしになる問題がありますが、renovateを使っていればこれも自動化・低コスト化できるのでその問題も解決できます。
まとめ
面倒なバージョンアップをスマートに支援してくれるRenovateバンザイ!
Sponsor
この記事はSpeee社内での知見を元にSpeeeの業務時間を使用して書かれました。
-
両方とも意味は同じ ↩