クイック修正
この問題を解決するには2つの方法があります。最も簡単なのは、ローカルのTerraform CLIをエラーに表示されているバージョンに合わせてアップグレードすることです。CI/CDの制約などでアップグレードできない場合は、ステートのメタデータを手動で調整する必要があります。以下に、3つのステップで行う「外科的」な修正手順を示します。
- ステートの取得:
terraform state pull > temp_state.json - バージョンの編集: ファイルを開き、
"terraform_version": "1.6.0"を必要なバージョン(例:"1.4.0")に変更します。 - ステートの反映:
terraform state push temp_state.json
なぜこれが発生するのか
Terraformはステートファイルを保護するように設計されています。terraform applyを実行するたびに、CLIはその時のバージョン番号をステートに刻印します。チームの1人がv1.6.0を使用し、他のメンバーがv1.4.0を使用している場合、その一度の「apply」によって他の全員がロックアウトされてしまいます。
古いバイナリは、新しいバージョンで作成されたステートファイルの読み取りを拒否します。これは、新しいバージョンで古いCLIが理解できないリソーススキーマが導入されている可能性があるため、データの破損を防ぐための安全策です。開発者がHomebrewやChocolateyで最新バージョンをインストールし、それが本番環境のバージョンよりも大幅に進んでいた場合に、この問題がよく発生します。
ステップバイステップの復旧手順
方法1:ステートのメタデータを手動でダウングレードする
古いバージョンのTerraformを使い続ける必要がある場合は、この方法を使用します。Terraformを騙して、古いバイナリで作成されたステートであると思い込ませます。
1. 現在のステートをダウンロードする リモートステートのローカルコピーを作成するために、以下のコマンドを実行します。これはS3、GCS、Azure Blob storageで動作します。
terraform state pull > repair_state.json
2. JSONを修正する
VS CodeやVimでrepair_state.jsonを開きます。冒頭にバージョン情報が見つかります。
{
"version": 4,
"terraform_version": "1.6.0",
"serial": 125,
...
}
terraform_versionの値を環境に合わせて変更します(例:1.4.0)。version: 4とserialフィールドはそのままにしてください。変更を保存します。
3. 修正したステートをアップロードする 修正したファイルをリモートバックエンドにプッシュします。Terraformはこれを手動更新として扱い、シリアル番号をインクリメントします。
terraform state push repair_state.json
ヒント: 「lineage」エラーが表示された場合は、ファイル構造が誤って変更されたことを意味します。バージョン文字列のみを変更したか確認してください。
方法2:tfenvでバージョンを同期する
ステートファイルを直接編集するよりも、同僚が使用しているバージョンに合わせる方が良い場合が多いです。バージョンマネージャーを使えば簡単です。ステートがv1.6.0であれば、そのバージョンに切り替えるだけです。
# 数秒でインストールと切り替え
tfenv install 1.6.0
tfenv use 1.6.0
# 変更を確認
terraform version
修正の確認
ステートをプッシュしたか、CLIを更新したら、planを実行してすべてが同期されているか確認します。
terraform plan
エラーは消えるはずです。ステートファイルをダウングレードした場合、planの結果は「No changes(変更なし)」となり、ローカルのコードとリモートのステートがようやく同じ言語を話していることが確認できます。
バージョンの乖離(ドリフト)を防ぐ方法
深夜2時の緊急事態を避ける最善の方法は、コード内でバージョンを固定することです。required_version制約を追加することで、ステートファイルを操作する「前に」、開発者が誤ったバージョンを使用するのを防ぐことができます。
terraform {
# 特定のマイナーバージョンに固定
required_version = "~> 1.4.0"
backend "s3" {
bucket = "my-terraform-state"
key = "prod/network.tfstate"
}
}
このブロックがあれば、誰かがv1.6.0を実行しようとした瞬間にエラーメッセージが表示されます。このシンプルなチェックにより、チームの同期が保たれ、不注意なアップグレードからステートファイルを保護できます。

