tfenvを使ってTerraformをインストールする

tfenvを使ってTerraformをインストールするのためのカバー画像

画像説明

Terraformの異なるバージョンに変更する必要がある時がきます。rbenv (Ruby用) や pyenv (Python用) のようなツールがあるように、tfenvTerraformの異なるバージョンをインストールするために使われる人気のツールです。

インフラ操作のほとんどのツーリングはamd64アーキテクチャと呼ばれるIntelプロセッサーで実行されますが、最近のMacbook M1の登場によりarm64アーキテクチャが使われています。Terraformの古いバージョンを必要とする場合は、Intelプロセッサー(amd64バイナリ)のみで利用可能なTerraformをインストールする必要があります。これもtfenvを使ってインストールすることができます。

この記事では次のセクションをカバーしています:

  1. Ubuntu (linux) とmacOS (darwin) に tfenv をインストールする
  2. Terraform の最新版または最近のバージョンをインストールする
  3. Armプロセッサ(Macbook M1/M2)が搭載されたmacOSにTerraformのレガシーバージョンをインストールする
  4. レガシーなプロバイダープラグインをインストールする(UbuntuとMacbook M1/M2)

Ubuntu (linux) またはmac OS (darwin) で tfenv をインストールする方法は以下の通りです。

Ubuntuにtfenvをインストールする

git clone https://github.com/tfutils/tfenv.git ${HOME}/.tfenv
export PATH="${HOME}/.tfenv/bin:${PATH}"
# 適切なシェル起動ファイル(例: $HOME/.bashrc)にインストールする
echo 'export PATH="$HOME/.tfenv/bin:$PATH"' >> ${HOME}/.profile

mac OSにtfenvをインストールする

brew install tfenv

tfenv をインストールしてパスに追加したら、以下のように実行するだけです:

tfenv install 1.3.7

tfenv list-remote を使えば、インストール可能なTerraformの様々なバージョンを検索できます。そこから、GNU grep を使って目的のバージョンを選択できます。例えば、最新バージョンをインストールする方法は以下の通りです:

LATEST_VERSION=$(tfenv list-remote \
 | grep -vP '\d.\d{0,2}.\d{0,2}-.*' \
 | head -1
)

tfenv install ${LATEST_VERSION}

macOSにはBSDフレーバーのgrepがあり、PCREをサポートしていません。PCRE をサポートする GNU Grep が必要な場合は、brew install grep を使用してください。

明示的なメジャーバージョンを GNU Grep に渡すことで、最後のマイナーバージョンを抽出できます:

# find latest 0.12
LATEST_0_12=$(tfenv list-remote  \
 | grep -oP '^0.12.\d{1,2}' \
 | sort --version-sort \
 | tail -1
)

tfenv install ${LATEST_0_12}

最新版が何であれ、以下を実行するだけでもインストールできます:

tfenv install latest

インストールされたバージョンのterraformを使用したい場合は、以下のように指定して選択できます:

tfenv use 1.3.7

Terraformを自動で切り替えるためには、.terraform-version をプロジェクトディレクトリに置いて、バージョンを自動選択できます:

mkdir -p  ${HOME}/my_project/.terraform-version
echo '1.3.7' > ${HOME}/my_project/.terraform-version

# Terraformのバージョンを自動で切り替える
cd ${HOME}/my_project/.terraform-version

Macbookがarm64プロセッサーを搭載している場合、macOSでamd64バイナリを実行するためにRosettaが必要になります。その後、以下のステップに従ってterraformのレガシーバージョンをインストールできます:

export TFENV_ARCH="amd64"

# arm64バイナリがないのでamd64バージョンのterraformをインストール
tfenv install 0.12.31
tfenv use 0.12.31

Terraformの最新バージョンでは、terraform init実行時にこのインストールが自動的に行われます。

まず、サポートされているTerraformバージョンに合った適切なプラグインバージョンを見つける必要があります。terraform-provider-kubectlの場合は、そのプラグインの1.11.2バージョンをインストールする必要があります。

Ubuntu Linuxでレガシープロバイダーをインストールする

ARCH="linux_amd64"
VERS="1.11.2"
PKG="terraform-provider-kubectl_${VERS}_${ARCH}.zip"
REPO="gavinbunney/terraform-provider-kubectl"
URL="https://github.com/${REPO}/releases/download/v${VERS}/${PKG}"

# このディレクトリがすでに存在しない場合はプラグインディレクトリをセットアップ
mkdir -p ${HOME}/.terraform.d/plugins/${ARCH}/

# アーカイブをダウンロードしてプラグインをインストール
pushd ${HOME}/Downloads
curl -sOL ${URL}
unzip ${PKG} && rm README.md LICENSE
mv terraform-provider-kubectl_v${VERS} \
  ${HOME}/.terraform.d/plugins/${ARCH}/
popd

Macbook M1でレガシープロバイダーをインストールする

arm64プロセッサーを搭載している現行のMacbookの場合、arm64ではなくamd64のレガシープロバイダーをインストールする必要があります。以下のように行います:

ARCH="darwin_amd64" # レガシーなterraform用にamd64プラグインをインストールする
VERS="1.11.2"
PKG="terraform-provider-kubectl_${VERS}_${ARCH}.zip"
REPO="gavinbunney/terraform-provider-kubectl"
URL="https://github.com/${REPO}/releases/download/v${VERS}/${PKG}"

# このディレクトリがすでに存在しない場合はプラグインディレクトリをセットアップ
mkdir -p $HOME/.terraform.d/plugins/${ARCH}/

# アーカイブをダウンロード
pushd ${HOME}/Downloads
curl -sOL ${URL}
unzip ${PKG} && rm README.md LICENSE
mv terraform-provider-kubectl_v${VERS} \
  ${HOME}/.terraform.d/plugins/${ARCH}/
popd

Terraformを使った冒険にこれが役立つことを願っています。Terraformのバージョンを固定する理由は、互換性がなくなる可能性のある重要な言語変更があるからです。インストーラー依存関係のチェーンは、terraformコマンドのターゲットバージョンに合わせなければならないでしょう。

さらに、プロバイダーとのインタラクションから生成されるステートも合わせる必要があるので、特定のバージョンのTerraformで作成されたインフラは、最終的にterraform destroyが使用された際に取り除かれることが重要です。

インフラが前進するにつれて、スムーズに移行するために使える技術があります。その方法の一つは、クラウドでのステートをデータソースを使って検索依存するモジュールモジュールを持つこと、さらに既存のインフラをterraform importを使ってステートにインポートすることです。これは将来の記事の素材になりそうです。

その間、tfenvのようなツールを使ってサポートされるバージョンを使用できます。tfenvに代わるもう一つのツールはasdfです。私はまだMacbook M1でのレガシーamd64バイナリのサポートを試していませんが、これも動作すると思います。asdfはさまざまな言語をサポートするプラグインアーキテクチャを持っていて便利です。

この記事についてですが、私は~の代わりに$HOMEを使い、簡単に$VARIABLEを使えばいい場面でカーリーブレースを使用した${VARIABLES}を使うことを選びました。これは、異なるプラットフォームで変数がシンタックスハイライトで色が強調されるために意図的に行いました。また$HOME~表記に慣れていない初心者のユーザー向けです。

こちらの記事はdev.toの良い記事を日本人向けに翻訳しています。
https://dev.to/joachim8675309/install-terraform-with-tfenv-1cg2