Terraformのtemplateプロバイダーを完全に撲滅する方法
templateプロバイダーとは
Terraformには以前までテンプレート処理を行うための template_fileのデータソースを提供する、templateプロバイダーが存在していました。
しかし現在ではtemplate_fileの使用は非推奨となっており、代わりにTerraformのVersion 0.12以降に登場した、Terraformの組み込み関数であるtemplatefileの使用が推奨されています。
templateプロバイダーのRepositoryは現在はArchiveになっています。
templateプロバイダーがあると困ること
Apple Silicon環境でtemplateプロバイダーを使用すると、以下のようなエラーが発生します。
$ terraform init
Initializing the backend...
Initializing modules...
Initializing provider plugins...
- Reusing previous version of hashicorp/aws from the dependency lock file
- Reusing previous version of hashicorp/template from the dependency lock file
- Installing hashicorp/aws v6.6.0...
- Installed hashicorp/aws v6.6.0 (signed by HashiCorp)
- Installing hashicorp/template v2.2.0...
Error: Failed to install provider
Error while installing hashicorp/template v2.2.0: the current package for registry.terraform.io/hashicorp/template 2.2.0 doesn't match any of the checksums previously recorded in the
dependency lock file; for more information: https://developer.hashicorp.com/terraform/language/files/dependency-lock#checksum-verification
これはtemplateプロバイダーがApple Silicon(darwin_arm64)向けにビルドされていないため、インストール時に検証に失敗しているのが原因です。
template_fileを消したのにエラーが発生
今回自分の環境で起きたこととして、ソースコード全体からtemplate_file -> templatefileへリファクタリングしたにもかかわらず、この状態で改めてinitを実行したら同じエラーが発生してしまいました。。
試したこと
リポジトリ全体を確認したところ、template_fileが残っていた時にinitをしていて.terraform/providers/以下にtemplateが残っていました。
また.terraform.lock.hclにもtemplateの記載があったので、一旦それらを手動で削除しました。
この状態で再度initを試してみたところ以下のエラーになりました。
若干エラー文は異なりますが、エラー自体はtemplateプロバイダーに起因しています。
$ terraform init
Error: Incompatible provider version
Provider registry.terraform.io/hashicorp/template v2.2.0 does not have a package available for your current platform, darwin_arm64.
Provider releases are separate from Terraform CLI releases, so not all providers are available for all platforms. Other versions of this provider may have different platforms supported.
ここで再度.terraform.lock.hclを確認したら、先ほどソースコードから削除したはずのtemplateの記載が復活していました...
$ cat .terraform.lock.hcl
:
provider "registry.terraform.io/hashicorp/template" {
version = "2.2.0"
hashes = [
"h1:I4FYYDOuNLmizSt4oo34Efh6EATor7WhE3wzNkFkylQ=",
]
}
原因と解消方法
ソースコードから削除しただけでは、Terraformのstateファイルにtemplateのリソース定義が残っているため、init時に再インストールされてしまったことが原因です。
以下のコマンドでtemplate_fileがstateに残っているかを確認できます。
$ terraform state list | grep template_file
module.example1.data.template_file.foo
module.example2.data.template_file.bar
リファクタリング済みで不要のため削除します。
$ terraform state rm module.example1.data.template_file.foo
$ terraform state rm module.example2.data.template_file.bar
この状態で再度initを実行すると、templateプロバイダーのインストールが行われず、エラーが解消されたことが確認できました!
$ terraform init
:
Terraform has been successfully initialized!
その他の解消方法
Apple Silicon対応ビルドを使う
template_fileは非推奨のため、組み込み関数のtemplatefileに移行するのがよいのですが、どうしてもtemplate_fileを使わなければならない場合は、Apple Silicon向けにtemplateプロバイダーをビルドできるツールがあります。
自分の場合は最初にこちらに辿り着き、無事に解消できたのでこの方法でも解消は可能です。
TFENV_ARCH=amd64を指定(旧回避策)
Terraformのバージョンが1.9.0?(どこから使えなくなるかの具体的な記述は見つかりませんでした)までは、Terraformインストール時にアーキテクチャをAmdに指定することで回避できましたが、現在のtemplate_fileは完全に互換性がなくなっており、この回避方法も取れなくなってしまいました。
$ TFENV_ARCH=amd64 tfenv install {version}
まとめ
今回のエラーはCPUアーキテクチャの違いが原因で発生します。
以前はTFENV_ARCH=amd64の指定で回避できましたが、TerraformのVersionによってはtemplate_file自体が互換性がなくなっています。
stateファイルに古いtemplate_fileの定義が残っていると、ソースコードから削除してもエラーが発生するため、state rmでの除去が確実な解決策だと思います。
同様の問題に遭遇した方の参考になれば幸いです。
Discussion