tfenvもしくはasdfでTerraformをバージョン管理してみた

2024/10/04

author

masyus

バージョン情報

  • macOS: Sonoma 14.4.1
  • tfenv: 3.0.0
  • asdf: v0.14.1

プロジェクト毎にTerraformのバージョンを切り替えたい

Google Cloudで複数プロジェクトを立ち上げて開発している時に遭遇したのですが、プロジェクト毎にリソースをTerraformで管理していると、開発が進むに連れてプロジェクト毎にTerraformのバージョンがずれていきます。それ自体は当然そうなるものなので仕方ないですが、ローカル開発環境でプロジェクトを切り替えて開発する度にTerraformのバージョンを切り替える方法が当初よくわかっていませんでした。

「どうやるのが良いだろう?」と調べていましたが、ひとまず「Terraform バージョン管理」でGoogle検索した時によく紹介されていたtfenvと、ツール全般のバージョン管理ができるasdfを試しに使ってみることにしました。今回はそれぞれの導入方法とTerraformのバージョン切り替え手順を、備忘録を兼ねて解説します。

tfenvとは

端的に言いますと、rbenvにinspiredされて作られたTerraform専用のバージョン管理です。macOS(Apple Silicon含む), Linux, Windowsに対応していますので、メジャーな環境下では問題なく動作しそうです。導入手順はGitHubリポジトリ上のREADMEに委ねますが、インストールが完了するとtfenvというコマンドが使えるようになります。

tfenvによるTerraformのバージョン切り替え手順

tfenv install {x.y.z}

で導入したいTerraformをインストールし、

tfenv use {x.y.z}

で利用したいTerraformのバージョンを切り替えます。

試しにTerraformの1.9.6と1.9.5をインストールして、バージョンを切り替えてみます。まずは1.9.6と1.9.5をインストールするところから始めます。

$ tfenv install 1.9.6
Installing Terraform v1.9.6
Downloading release tarball from https://releases.hashicorp.com/terraform/1.9.6/terraform_1.9.6_darwin_arm64.zip
############################################################# 100.0%
Downloading SHA hash file from https://releases.hashicorp.com/terraform/1.9.6/terraform_1.9.6_SHA256SUMS
Not instructed to use Local PGP (/usr/local/Cellar/tfenv/3.0.0/use-{gpgv,gnupg}) & No keybase install found, skipping OpenPGP signature verification
Archive:  /var/folders/px/v7k_c_3j5fl65wfq_pzl3qhh0000gn/T/tfenv_download.XXXXXX.jwJIi4mgjr/terraform_1.9.6_darwin_arm64.zip
  inflating: /usr/local/Cellar/tfenv/3.0.0/versions/1.9.6/LICENSE.txt
  inflating: /usr/local/Cellar/tfenv/3.0.0/versions/1.9.6/terraform
Installation of terraform v1.9.6 successful. To make this your default version, run 'tfenv use 1.9.6'

$ tfenv install 1.9.5
Installing Terraform v1.9.5
Downloading release tarball from https://releases.hashicorp.com/terraform/1.9.5/terraform_1.9.5_darwin_arm64.zip
############################################################# 100.0%
Downloading SHA hash file from https://releases.hashicorp.com/terraform/1.9.5/terraform_1.9.5_SHA256SUMS
Not instructed to use Local PGP (/usr/local/Cellar/tfenv/3.0.0/use-{gpgv,gnupg}) & No keybase install found, skipping OpenPGP signature verification
Archive:  /var/folders/px/v7k_c_3j5fl65wfq_pzl3qhh0000gn/T/tfenv_download.XXXXXX.PjmP8dbjzT/terraform_1.9.5_darwin_arm64.zip
  inflating: /usr/local/Cellar/tfenv/3.0.0/versions/1.9.5/LICENSE.txt
  inflating: /usr/local/Cellar/tfenv/3.0.0/versions/1.9.5/terraform
Installation of terraform v1.9.5 successful. To make this your default version, run 'tfenv use 1.9.5'

無事にインストール完了しました。次にバージョン切り替えです。1.9.6 → 1.9.5 → 1.9.6と切り替えてみます。

$ terraform -v
Terraform v1.9.6
on darwin_arm64

$ tfenv use 1.9.5
Switching default version to v1.9.5
Default version (when not overridden by .terraform-version or TFENV_TERRAFORM_VERSION) is now: 1.9.5

$ terraform -v
Terraform v1.9.5
on darwin_arm64

$ tfenv use 1.9.6
Switching default version to v1.9.6
Default version (when not overridden by .terraform-version or TFENV_TERRAFORM_VERSION) is now: 1.9.6

$ terraform -v
Terraform v1.9.6
on darwin_arm64

このようになりました。

tfenv総論

基本的なバージョン切り替え操作はtfenv installtfenv useで対応できるため、使い勝手はシンプルで良さそうに感じました。懸念点があるとしたら、GitHubリポジトリ上で最後にタグが切られたのが2022年7月15日のv3.0.0で、以降は更新が停滞している点です。

asdfとは

あらゆるランタイムのバージョンを1つのツールで管理することが可能なバージョン管理です。つまり

Terraformに限らず、他のランタイムもasdfでバージョン管理可能

とのこと。こちらもメジャーなOS環境下で動作します。導入手順は公式ドキュメントに委ねますが、インストールが完了するとasdfというコマンドが使えるようになります。

asdfによるTerraformのバージョン切り替え手順

asdfではバージョン管理したいツールのことをpluginと呼びます。バージョン切り替えの手順としては

  • pluginを追加する
  • 追加したpluginのバージョンを追加する
  • 追加したpluginのバージョンを切り替える

の3段階の流れとなります。

1. asdfでpluginを追加する

まずは自身がバージョン管理したいツールがasdfのpluginに存在するかを確認します。どのツールがasdfに対応しているかをざっくり把握するには、GitHubリポジトリのasdf-vm / asdf-plugins > Plugin Listのテーブルから調べられます。但しこのテーブルには正式なplugin名の記載がないため、テーブルで当たりをつけた後に

asdf plugin list all | grep {plugin名}

を実行し、pluginを追加する際のplugin名を検索します。Terraformの場合、下記になりました。

$ asdf plugin list all | grep terraform
iam-policy-json-to-terraform  https://github.com/carlduevel/asdf-iam-policy-json-to-terraform.git
terraform                     https://github.com/asdf-community/asdf-hashicorp.git
terraform-docs                https://github.com/looztra/asdf-terraform-docs.git
terraform-ls                  https://github.com/asdf-community/asdf-hashicorp.git
terraform-lsp                 https://github.com/bartlomiejdanek/asdf-terraform-lsp.git
terraform-validator           https://github.com/looztra/asdf-terraform-validator.git
terraformer                   https://github.com/gr1m0h/asdf-terraformer.git

plugin名はterraformで良さそうです。次にTerraformのpluginを追加します。

asdf plugin add terraform

を実行して追加完了します。ただ、追加に成功しても何も出力されないため、完了したかが少々わかりづらいです。その場合は

asdf plugin list

を実行することで、追加したpluginを確認することができます。

$ asdf plugin list
terraform

無事にterraformが追加されていることが確認できました。

2. asdfで追加したpluginのバージョンを追加する

asdf list all terraform

pluginを追加完了し、上記コマンドを実行するとインストール可能なバージョンがリストアップされます。今回はtfenvの検証で用いたTerraformの1.9.6と1.9.5をインストールしてみます。

$ asdf install terraform 1.9.6
Downloading terraform version 1.9.6 from https://releases.hashicorp.com/terraform/1.9.6/terraform_1.9.6_darwin_arm64.zip
Skipping verifying signatures and checksums either because gpg is not installed or explicitly skipped with ASDF_HASHICORP_SKIP_VERIFY
Cleaning terraform previous binaries
Creating terraform bin directory
Extracting terraform archive

$ asdf install terraform 1.9.5
Downloading terraform version 1.9.5 from https://releases.hashicorp.com/terraform/1.9.5/terraform_1.9.5_darwin_arm64.zip
Skipping verifying signatures and checksums either because gpg is not installed or explicitly skipped with ASDF_HASHICORP_SKIP_VERIFY
Cleaning terraform previous binaries
Creating terraform bin directory
Extracting terraform archive

3. 追加したpluginのバージョンを切り替える

asdfでは使用するpluginのバージョンを

  • global: OS内のどのディレクトリにいても
  • shell: 現在のshellのセッションにだけ
  • local: 特定のディレクトリにだけ

の3種で適用設定することができます。概念的にはscopeのようなものと捉えれば良いかと思われます。globalとlocalで設定すると.tool-versionsというファイルがそれぞれ$HOME/, $PWD/配下に作成され、そこにpluginのバージョン情報が記録されます。shellの場合は環境変数に記録されます。

どれを使うのが適切なのかは運用方法次第ですが、取り急ぎ今回はglobalを指定して、Terraformのバージョンを1.9.6 → 1.9.5 → 1.9.6と切り替えてみます。

asdf global terraform 1.9.6
cat ~/.tool-versions
terraform -v

asdf global terraform 1.9.5
cat ~/.tool-versions
terraform -v

asdf global terraform 1.9.6
cat ~/.tool-versions
terraform -v

実行結果は下記になりました。

$ asdf global terraform 1.9.6
$ cat ~/.tool-versions
terraform 1.9.6
$ terraform -v
Terraform v1.9.6
on darwin_arm64

$ asdf global terraform 1.9.5
$ cat ~/.tool-versions
terraform 1.9.5
$ terraform -v
Terraform v1.9.5
on darwin_arm64

$ asdf global terraform 1.9.6
$ cat ~/.tool-versions
terraform 1.9.6
$ terraform -v
Terraform v1.9.6
on darwin_arm64

確かに切り替わっていることが確認できました。

globalとlocalが混在する環境下ではどうなる?

たとえば$HOME/, $PWD/それぞれの配下に.tool-versionsがあり、Terraformのバージョンが

  • $HOME/.tool-versions: terraform v1.9.6
  • $PWD/.tool-versions: terraform v1.9.5

であるとします。カレントディレクトリが$PWDの場合、

$ terraform -v
Terraform v1.9.5
on darwin_arm64

となります。つまりlocalの設定値がglobalの設定値よりも優先される挙動です。

asdf総論

バージョン管理したいツールをpluginとして指定するプロセスがあるため、tfenvと比較すると手順がやや多い印象です。ですが、バージョン管理したいツールが複数ある場合は、asdfのほうが管理が一元化されて便利に感じます。

tfenvとasdfの使い分け

  • 単にTerraformだけバージョン管理したい場合: tfenv
  • 複数のツールをバージョン管理したい場合: asdf

が良さそうです。

Terraformの実運用を想定した場合、たとえばTerraformの静的解析ツールであるtfsec(昨今はTrivyへ移行している様子)やLinterのTFlintも一緒に活用し、まとめてバージョン管理したくなるかと思います。その場合はasdfを使うのが良さそうに思いました。

また、Node.jsのバージョン管理(nvm, n, ...etc.)やRubyのバージョン管理(rbenv)から脱却し、単一の管理手法でまとめてバージョン管理したいニーズにもasdfなら答えられます。

参考

Node.jsの関連記事

まだ記事がありません

Rubyの関連記事

まだ記事がありません