🦖

Terraformの「Incompatible provider version」エラーを解消した話

に公開

今回は、Apple Silicon環境でTerraformを実行した際に遭遇した、hashicorp/templateプロバイダーが原因のエラーと、その解消方法について共有したいと思います。

事象と背景

ある日、M1 Mac上でTerraformのプロジェクトをビルドしようとしたところ、以下のようなエラーが出て先に進めませんでした。

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.

「hashicorp/templateプロバイダーがApple Silicon向けバイナリを提供していない」 ため、Terraformの初期化に失敗するという状況でした。

しかし手元のTerraformコードを一通り検索してみても、template プロバイダーなんて使っていない……。それなのに、なぜか毎回 template がダウンロードされようとしてエラーになってしまいます。

課題

1. Apple Silicon向けのバイナリが存在しない

template プロバイダーは最終版(v2.2.0)以降メンテナンスされておらず、darwin_arm64 用がそもそもリリースされていません。

2. コード上では使っていないはずなのにインストールされようとする

• 過去のStateに情報が残っている
• サブモジュール(古いモジュール)が内部的に template_file を参照している
• .terraform.lock.hcl や .terraform/ のキャッシュに古い依存が残っている

この2点が組み合わさって、ただの terraform init が進まず困ってしまいました。

原因と解決方法

1. template プロバイダーの実際の利用箇所を探す

まずは、本当に今でも使っていないかを確認します。
• git grep template
• terraform providers

これでヒットしなければ、コード上からは削除済みの可能性が高い。
しかし「State」か「サブモジュール」がまだ依存しているかもしれません。

2. Terraform Stateからの削除

もしコードにはないのに残っている場合、State内のプロバイダー参照を破棄する必要があります。
terraform state replace-provider コマンドを使い、hashicorp/template を hashicorp/null などに置き換えると、Terraformが「もうtemplateは不要だな」と認識してくれます。

念のため現在のstateをバックアップ

terraform state pull > backup.tfstate

templateプロバイダーからnullプロバイダーへ置き換える

terraform state replace-provider \
    registry.terraform.io/hashicorp/template \
    registry.terraform.io/hashicorp/null

置き換えが成功したら、.terraformディレクトリや.terraform.lock.hclを削除し、改めて terraform init -upgrade を実行してください。これで「templateプロバイダーをダウンロードしない」状態を再構築できます。

3. まだ data "template_file" を使っている場合は templatefile() へ置き換え

もし古いモジュールや自分のコードで data "template_file" を使っているのであれば、Terraform組み込み関数の templatefile() を使う形に移行しましょう。Terraform v0.12以降ではこちらが推奨されており、追加のプロバイダー不要です。

例えば以下のように書き換えます。

旧: templateプロバイダー + data "template_file"
data "template_file" "example" {
  template = file("${path.module}/my_template.tpl")
  vars = {
    foo = "bar"
  }
}

resource "some_resource" "example" {
  content = data.template_file.example.rendered
}

新: 組み込み関数 templatefile()

locals {
  my_rendered_template = templatefile(
    "${path.module}/my_template.tpl",
    { foo = "bar" }
  )
}

resource "some_resource" "example" {
  content = local.my_rendered_template
}

これで data "template_file" と template プロバイダーの宣言を削除すれば、Apple Silicon環境でもエラーを起こさずにTerraformが動作するようになります。

まとめ

• Apple Silicon向けバイナリのない template プロバイダーが原因で、Terraformがエラーを起こしていました。
• コード上の参照を削除しただけでは不十分で、Stateやロックファイルに残っていないかもチェックが必要です。
• terraform state replace-provider を使って不要なプロバイダー依存を取り除くか、もしくは templatefile() 関数で書き換えてプロバイダーを利用しない構成にすれば、無事初期化に成功します。

私の場合、State中に template が残っているのが原因だったため、置き換えコマンドで解消できました。もし同じような問題に直面している方がいれば、ぜひこの方法を試してみてください。

以上、Apple Silicon環境でのTerraformプロバイダーエラー解消に関するトラブルシュート報告でした。参考になれば幸いです。

Discussion