PowerShell版の tfenv(のようなもの) をつくってみた

2022.10.13

しばたです。

以前Terraform用のPowerShellモジュールを作った記事を公開しました。

その後「コレ、ちょっと工夫したらtfenvと同じもの作れるんじゃね?」と思い、軽くプロトタイプを書いてみたらよい感じだったのでそのまま勢いに任せて実装しました。

tfenvはシェルスクリプト(Bashスクリプト)の集合体であり、Windows環境においては「Git Bashでだけテストしてる」といった状況です。
私の作ったツールはPowerShell 7用でありPowerShell 7がインストールされていればWindows含めてクロスプラットフォームで動作します。Windows環境向けと考えればこのツールの存在価値もそれなりにあると思っています。(まあ、もう作ってしまったので存在価値が無くても私は使います...)

TFAlias

今回のツールは前回のモジュール TerraformUtilTFAliasの名前が付く関数として実装しています。

インストール手順は前回と変わりありません。

# インストールは前回と同じでInstall-Moduleを使う
Install-Module -Name TerraformUtil -Force

Set-TFAlias

モジュールのインストール後Set-TFAlias -Initializeコマンドを実行すると初期設定を行います。
初期設定では以下の作業を行います。

  1. $HOME\.tfalias\ フォルダを作成し、必要なファイル群をコピー
  2. 最新バージョンのTerraformバイナリをダウンロードし $HOME\.tfalias\ 配下にインストール
  3. ダウンロードしたTerraformに対するエイリアスを設定
# 初期設定 + 最新バージョンのTerraformをインストール
PS C:\> Set-TFAlias -Initialize
Create path : C:\Users\shibata\.tfalias\terraform
Create path : C:\Users\shibata\.tfalias\bin
Use the latest version of Terraform.
Terraform v1.3.2 is the latest version.
Install Terraform v1.3.2 to C:\Users\shibata\.tfalias\terraform\1.3.2...
Binary file is saved to C:\Users\shibata\.tfalias\terraform\1.3.2
Set the v1.3.2 terraform alias.

ざっくりtfenv use latestと同等だと考えて頂ければOKです。
このツールではPowerShellのエイリアスを使うのでPATHを通す必要はありません。

この状態でterraformコマンドを実行すると以下の様に最新バージョンが実行されます。

# 本日時点で最新のTerraformが実行される
PS C:\> terraform version
Terraform v1.3.2
on windows_amd64

# terraformコマンドの実体はエイリアス
PS C:\> Get-Command terraform | Select-Object CommandType, Definition

CommandType Definition
----------- ----------
      Alias C:\Users\shibata\.tfalias\bin\terraform.ps1

違うバージョンのTerraformを実行したい場合はSet-TFAlias -Versionコマンドを実行します。
初回実行時は当該バージョンのTerraformをダウンロードします。

# Set-TFAlias -Version で指定バージョンのTerraformを使用
PS C:\> Set-TFAlias -Version 1.2.3
Install Terraform v1.2.3 to C:\Users\shibata\.tfalias\terraform\1.2.3...
Binary file is saved to C:\Users\shibata\.tfalias\terraform\1.2.3
Set the v1.2.3 terraform alias.

PS C:\> terraform version
Terraform v1.2.3
on windows_amd64

Your version of Terraform is out of date! The latest version
is 1.3.2. You can update by downloading from https://www.terraform.io/downloads.html

改めて最新バージョンを使いたい場合のためにSet-TFAlias -Latestコマンドも用意しています。

# Set-TFAlias -Latest で最新バージョンのTerraformを使用
C:\> Set-TFAlias -Latest
Terraform v1.3.2 is the latest version.
Set the v1.3.2 terraform alias.

Get-TFInstalledAlias

インストールされたTerraformはGet-TFInstalledAliasコマンドで確認できます。
ざっくりtfenv listと同等です。

# インストールされたTerraformの一覧を取得
PS C:\> Get-TFInstalledAlias

Current Version Path
------- ------- ----
  False 1.3.2   C:\Users\shibata\.tfalias\terraform\1.3.2\terraform.exe
   True 1.2.3   C:\Users\shibata\.tfalias\terraform\1.2.3\terraform.exe

Uninstall-TFAlias

Terraformをアンインストールしたい場合はUninstall-TFAliasコマンドを使います。
ざっくりtfenv uninstallと同等です。

# Uninstall-TFAlias で指定バージョンをアンインストール
PS C:\> Uninstall-TFAlias -Version 1.3.2
Uninstall Terraform v1.3.2

# 結果確認
PS C:\> Get-TFInstalledAlias

Current Version Path
------- ------- ----
   True 1.2.3   C:\Users\shibata\.tfalias\terraform\1.2.3\terraform.exe

.terraform-version ファイルのサポート

tfenvと同様にこのツールも.terraform-versionファイルをサポートします。

ただ、tfenvではTerraformのバージョン判定をgrepベースでかなり強引にやっており若干の制限があるのですが、このツールではもう少し正確に判定できる様にしています。
この点はtfenvと挙動が異なります。

// min-required を指定された場合の挙動が異なる

// tfenv は 0.12.3 を返すが Set-TFAlias は 0.10.0 と判定する
terraform {
  required_version  = "<0.12.3, >= 0.10.0"
}
// latest-allowed を指定された場合の挙動が異なる

// tfenv はエラーになるが Set-TFAlias は 0.12.2 と判定する
terraform {
  required_version  = "<0.12.3, >= 0.10.0"
}

正直そんなに使う部分じゃないと思ってるので意図して挙動を変えています。
あと一応tfenv pinに相当するSet-TFAlias -Pinコマンドも用意してますが、正直なところ「これ要る?」って今も思っています。

# 一応 Set-TFAlias -Pin コマンドも作った
PS C:\> cd C:\temp\
PS C:\temp> Set-TFAlias -Pin
Pinned version by writing "1.2.3" to C:\temp\.terraform-version

# .terraform-version がある場合の挙動はこんな感じ
PS C:\temp> Set-TFAlias -Version 1.3.0
WARNING: Preferred version.1.2.3 is detected from C:\temp\.terraform-version.
WARNING: Override version 1.3.0 to 1.2.3
Set the v1.2.3 terraform alias.

TFAlias for Command Prompt

このツールはPowerShell 7用ですが、コマンドプロンプトやWindows PowerShellからも使える様に専用のコマンド tfalias.cmd を用意しました。

tfalias.cmdSet-TFAlias -Initializeコマンド実行後に$HOME\.tfalias\bin\フォルダにインストールされます。
このため初期設定だけはPowerShell 7を使います。

その後で$HOME\.tfalias\bin\フォルダにPATHを通してやればOKです。
こちらはコマンド体系をtfenvにかなり寄せています。

REM 最新バージョンのTerraformを使用
C:>tfalias use latest
Terraform v1.3.2 is the latest version.
Set the v1.3.2 terraform alias.

REM Terraform v1.2.3を使用
C:>tfalias use 1.2.3
Set the v1.2.3 terraform alias.

REM インストールされたTerraformの一覧を取得
C:>tfalias list
  1.3.2
* 1.2.3

REM ピン止め
C:>cd .\temp
C:\temp>tfalias pin
Pinned version by writing "1.2.3" to C:\temp\.terraform-version

内部的には都度pwsh.exeを起動して所定の関数を実行しています。
プロセス起動の分若干動作が遅めです。

さらに派生としてWindows PowerShell(5.0 - 5.1)やNushellでも使えたりします。

(Windows PowerShellから実行した場合)

(Nushellから実行した場合)

PowerShell 7で関数を実行した場合と同等の使用感になっているはずです。

(PowerShell 7で関数を利用した場合)

所感

やっていることは完全に車輪の再発明なんですが、作ってる本人にとっては多くの学びがあり楽しいです。
もとのtfenvのソースや挙動を見ながら自分でソースを書くことで設計思想や実装の良いところ・悪いところが見えてきますし、それを踏まえつつ「自分ならこう実装する。」、「PowerShellの流儀に合わせるとこの設計の方がベターかな?」と言った感じで自分なりの考えが深まっていきました。

ちなみに非Windows環境であれば普通にPowerShell上でtfenvが動作します。 *1
このため非Windows環境はわざわざこのツールを使う必要も無く、差別化をどこで実現しようか考えるのも勉強になりました。

私としては、

  • Windows環境でtfenvと同等の機能を実現する
  • PowerShellの世界観に沿った使い勝手を実現する

という点をこのツールの軸に置いています。

最後に

以上となります。

WindowsでTerraformを使っている人がどの位いるかわかりませんが、よければこのツールを使ってみてください。

脚注

  1. PowerShellからBashスクリプトを呼ぶ形になるだけなので...