電気ひつじ牧場

技術メモと日常のあれこれ

【Terraform】CIでinitした時にdoesn't match any of the checksums previously recorded in the dependency lock fileとなる

codebuildでterraform initをした時に下記のようなエラーが出力されて落ちた

Initializing provider plugins...
- Reusing previous version of hashicorp/aws from the dependency lock file
- Installing hashicorp/aws v3.42.0...

Error: Failed to install provider

Error while installing hashicorp/aws v3.42.0: the current package for
registry.terraform.io/hashicorp/aws 3.42.0 doesn't match any of the checksums
previously recorded in the dependency lock file

メッセージを読むと、どうやらリポジトリ.terraform.lock.hclに含まれているproviderのハッシュ値が一致しないことが原因となっている模様。

.terraform.hcl.lock

依存しているproviderとそのバージョンを固定するlockファイルであり、Terraform0.14から導入された。多くの言語に備わっているpackage.lockなどの仕組みと似ている。

terraform initを実行した際、.terraform.hcl.lockに.tfで宣言しているproviderの記述がなければバージョン制約に基づいて最新のものを取得した後、その情報をlockファイルに書き込む。記述があればそれと同じバージョンを取得する。

この時同時にlockファイルのproviderに付随しているチェックサムをもとに、initで取得したproviderと一致するかの検証が行われ、*1検証が失敗するとinitは失敗する。

原因

ローカルでterraform initした時に記述された.terraform.hcl.lockに含まれるproviderのチェックサムが、CI上でinitした時に取得・計算されたproviderのチェックサムと一致しなかったことが原因。ローカルとリモートでOSなどのプラットフォームが異なっていたり、ローカルでProvider Plugin Cache*2を使っている場合にチェックサムの不一致が生じてしまう。

対処

terraform providers lockというコマンドを利用することで事前に複数のプラットフォーム向けにチェックサムを生成し、.terraform.hcl.lockを生成することができる。例えば、ローカルのmacOSとCI上のLinuxでinitを実行する場合、ローカルで次のコマンドを実行することで.terraform.hcl.lockを生成する。

$ terraform providers lock \
  -platform=darwin_amd64 \  # 64-bit macOS
  -platform=linux_amd64     # 64-bit Linux

参考

実際にはもっと複雑な事情があるらしい。 speakerdeck.com

www.terraform.io

www.terraform.io

*1:SSHのknown_hostsの仕組みと同じくtrust on first useを採用している

*2:https://www.terraform.io/docs/cli/config/config-file.html#provider-plugin-cache