Terraformを使い始めてしばらくすると出会う課題が、プロジェクトで使用するTerraformバージョンを制約しつつ、Terraform利用者のインストール手間を減らすことです。 Terraformはバージョンアップによって挙動が変わりえるため、プロジェクトで利用するバージョンはある程度固定したくなります。しかし1つのTerraformですべての環境をそろえるのは難しいでしょう。例えば横断的なやり取りのないプロジェクトでは異なるバージョンのTerraformを使っているでしょう1し、Terraformアップグレード時にそのブランチだけ異なるバージョンを使いたくなります。
このように「実行環境ごとに異なるバージョンのTerraformを利用している」時に、環境ごとに自動的にバージョンを切り替えるツールとしてtfenvとtenvがあります。今回はtenvを使って、バージョンアップ時の手間を減らしつつ、環境ごとのTerraformバージョンを自動的に切り替える方法を紹介します。
tenvとは
tenvはTerraformのバージョン管理ツールです。tfenvと同様に、環境ごとに異なるTerraformバージョンを使いたいときに利用します。tfenvは2022年を最後にリリースが止まっており利用は避けたい状況です。tenvはtfenv同様に利用できつつも実装がGoであるため、Bashで作られていたtfenvと違ってWindowsを含めたマルチOS環境でネイティブに動作します。私自身がTerraformのヘビーユーザーですが、現時点でterraformを管理するツールはtenvが最もおすすめです。
tenvをインストールする
tenvのインストールは、バイナリ配置、パッケージマネージャー経由、go installなどいろんな方法があります。詳しくはREADMEを見るといいです。私は次の方法でインストールしています。
Linux
aquaを使って管理しています。
# aqua.yaml registries: - type: standard ref: v4.219.0 # renovate: depName=aquaproj/aqua-registry packages: - name: tofuutils/tenv@v4.1.0
aqua install
macOS
homebrewで管理しています。
brew install tenv
Windows
scoopで管理しています。
scoop install tenv
Terraformを実行したいときにtenvに自動インストールさせる
tenvには、そのTerraformディレクトリで必要なTerraforバージョンを示したファイルを配置することで、terraformコマンドを実行するときに自動的に指定されたTerraformバージョンをインストールしてする機能があります。これを使うと、プロジェクトごとに異なるバージョンのTerraformを使っていても透過的に切り替わるので、開発者にいちいちバージョンを切り替えてもらう手間を省けます。
これを利用するには、環境変数でTENV_AUTO_INSTALL=true
を指定しておく必要があります。.bashrcや.zshrc、profile.ps1などに設定しておくといいでしょう。
# Windows (cmd) set TENV_AUTO_INSTALL=true # Windows (PowerShell) $env:TENV_AUTO_INSTALL = "true" # Linux/macOS export TENV_AUTO_INSTALL=true
これでterraformコマンドを実行ディレクトリに.terraform-version
ファイルがあれば、自動的に指定バージョンをインストールして実行します。例えば、次のようなファイルを配置すると、実行時に1.10.3をインストールしします。
1.10.3
ここまでがtenvの基本的な使い方です。tenvは他にもいろいろな機能があるので、興味がある人はREADMEを見てください。
tenvを使ってterraformのrequired_versionに指定したバージョンを自動的に利用させる
よく見かけるのが、terraformのrequired_version
を固定指定2しつつ、.terraform-versionでもそのバージョンを記載する方法です。期待通り指定したバージョンだけで動作するのですが、二重定義しているのでアップグレード時に漏れる可能性があります。
設定箇所 | 設定する値 |
---|---|
terraformのrequired_version | = 1.10.3 や~> 1.10.0 |
.terraform-version | 1.10.3 |
Terraform Cloudのバージョン | 1.10.3 |
GitHub Actionsのバージョン | 1.10.3 |
terraform
# versions.tf など terraform { required_version = "= 1.10.3" }
.terraform-version
# .terraform-version
1.10.3
Terraform Cloud
Terraform CloudのRemote Executionを使っている場合、Terraform Cloud側のバージョンとも一致しないといけないため3箇所に増えて手間がかかります。
GitHub Actions
CIを使っている場合、そのTerraformバージョンも合わせる必要があります。GitHub Actionsならsetup-terraform
を使うことが多いでしょう。
- uses: hashicorp/setup-terraform@v3 with: terraform_version: "1.10.3" cli_config_credentials_token: ${{ secrets.TF_API_TOKEN }}
バージョン指定を一箇所にまとめる
Terraformのバージョン更新をrenovateで管理するのもいいですが、バージョン指定を一箇所にまとめる方法もあります。tenvを使って.terraform-versionにはlatest-allowed
を指定しておき、terraformのrequired_version
にはそのマイナーバージョンにおける最新パッチを使うように指定します。これにより、ファイル上のterraformのバージョンをrequired_version
一箇所にまとめることができます。Terraform Cloudも1.10.x
の間は変更不要です。
設定箇所 | 設定する値 |
---|---|
terraformのrequired_version | ~> 1.10.0 |
.terraform-version | latest-allowed |
Terraform Cloudのバージョン | ~> 1.10.0 latest |
GitHub Actionsのバージョン | required_versionの値を自動設定 |
latest-allowed
を指定する方法はtenvのREADMEにも書かれています。
The latest-allowed strategy rely on required_version from .tf or .tf.json files with a fallback to latest when no constraint are found. Moreover it is possible to add a default constraint with TFENV_TERRAFORM_DEFAULT_CONSTRAINT environment variable or ${TENV_ROOT}/Terraform/constraint file (can be written with tenv tf constraint). The default constraint is added while using latest-allowed, min-required or custom constraint. A default constraint with latest-allowed or min-required will avoid the fallback to latest when there is no .tf or .tf.json files.
terraform
# versions.tf など terraform { required_version = "~> 1.10.0" }
.terraform-version
# .terraform-version
latest-allowed
Terraform Cloud
1.10.0
というマイナーバージョンの間は変更不要です。
GitHub Actions
terraformのrequired_versionを利用するように変更します。これで常にrequired_version
の値を利用します。
- name: Get terraform version from .terraform-version shell: bash id: terraform-version run: | required_version=$(grep -E 'required_version\s*=\s*"([^"]+)"' "versions.tf" | sed -n 's/.*required_version\s*=\s*"\([^"]*\)".*/\1/p') echo "value=$required_version" | tee -a "${GITHUB_OUTPUT}" working-directory: ${{ inputs.working-directory }} - uses: hashicorp/setup-terraform@v3 with: terraform_version: ${{ steps.terraform-version.outputs.value }} cli_config_credentials_token: ${{ secrets.TF_API_TOKEN }}
動作確認
動作確認をしてみましょう。required_verseionには1.9.0のマイナーバージョン以内
を指定し、.terraform-versionにrequired_versionの制約で可能な最新を指定します。
$ cat ./versions.tf | grep required_version required_version = "~> 1.9.0" $ cat .terraform-version latest-allowed
Windows
環境変数を設定した状態でterraformを実行すると最新バージョンの1.9.8が自動的にインストールされています。
$ set TENV_AUTO_INSTALL=true $ terraform init Resolved version from D:\github\guitarrapc\Test\aws_test\.terraform-version : latest-allowed Scan project to find IAC files No compatible version found locally, search a remote one... Fetching all releases information from https://releases.hashicorp.com/terraform/index.json Found compatible version remotely : 1.9.8 Installing Terraform 1.9.8 Fetching release information from https://releases.hashicorp.com/terraform/1.9.8/index.json Downloading https://releases.hashicorp.com/terraform/1.9.8/terraform_1.9.8_windows_amd64.zip Downloading https://releases.hashicorp.com/terraform/1.9.8/terraform_1.9.8_SHA256SUMS Downloading https://releases.hashicorp.com/terraform/1.9.8/terraform_1.9.8_SHA256SUMS.sig Downloading https://www.hashicorp.com/.well-known/pgp-key.txt Installation of Terraform 1.9.8 successful Initializing HCP Terraform... $ terraform --version Terraform v1.9.8 on windows_amd64
Linux
環境変数を設定した状態でterraformを実行すると最新バージョンの1.9.8が自動的にインストールされています。
$ export TENV_AUTO_INSTALL=true $ terraform init Resolved version from /mnt/d/github/guitarrapc/Test/aws_test/.terraform-version : latest-allowed Scan project to find IAC files No compatible version found locally, search a remote one... Fetching all releases information from https://releases.hashicorp.com/terraform/index.json Found compatible version remotely : 1.9.8 Installing Terraform 1.9.8 Fetching release information from https://releases.hashicorp.com/terraform/1.9.8/index.json Downloading https://releases.hashicorp.com/terraform/1.9.8/terraform_1.9.8_linux_amd64.zip Downloading https://releases.hashicorp.com/terraform/1.9.8/terraform_1.9.8_SHA256SUMS Downloading https://releases.hashicorp.com/terraform/1.9.8/terraform_1.9.8_SHA256SUMS.sig Downloading https://www.hashicorp.com/.well-known/pgp-key.txt Installation of Terraform 1.9.8 successful Initializing HCP Terraform...
Windows、LinuxとOSが異なっても同じ使い勝手でTerraformのバージョンを自動的に切り替えてくれています。
まとめ
terraformのバージョン管理はtenvを使うと便利です。tenvで透過的にTerraformバージョンを利用させるには.terraform-version
にlatest-allowed
を指定すると楽になります。
CIやTerraform Cloudも含めてなるべくバージョン変更箇所を減らすようにすると、バージョンアップ時の手間を減らすことができます。小さな手間の積み重ねが大きな手間を減らすことにつながるのでやっていきましょう。
AIが勝手に更新してくれるようになるといいですね。Renovateもいい手段ですが、本記事のやり方も便利です。