Terragrunt を使っていたら、ディスクがいつの間にか埋まっていた!
こんにちは Terragrunt 使いです!
最近 Macから「ディスク容量足りない!」とお叱りを受けることがあり、原因を調査していたのですが、その調査中に異常にサイズが肥大しているterragruntのプロジェクトを発見しました。
$ du -h -d 1
...
とあるTerragruntプロジェクトのディレクトリ 30GB (!?)
...
おまえかー!!
そしてそのプロジェクトの中を調査してみると、どうやらプロジェクトが肥大していた原因は terragrunt apply
のたびに作成される .terragrunt-cache
ディレクトリのようでした。
.terragrunt-cache
ディレクトリとはなんでしょう? 公式ドキュメントによると、一部のキャッシュ(削除可能なデータ)を保存しておくためのもののようです。
Terragrunt creates a
.terragrunt-cache
folder in the current working directory as its scratch directory. It downloads your remote Terraform configurations into this folder, runs your Terraform commands in this folder, and any modules and providers those commands download also get stored in this folder. You can safely delete this folder any time and Terragrunt will recreate it as necessary.
実際、Terragruntを実行すると以下が .terragrunt-cache
ディレクトリに作成されます。
-
aws-provider
などのTerraformプラグイン類 (Goバイナリ)-
provider-aws
だと 350MB前後ぐらい - 今回のディスク容量不足はこれが原因
-
- Terragrunt内で
source = "..."
で参照しているディレクトリ(リポジトリ)- プロジェクトにもよるが大きくても数MBなので大したサイズではない
- state ファイル
- 他と比較できるほど大きなサイズになっていることはないと思われる
一般的にTerragruntプロジェクトはモジュールおよび状態(ステート)の管理単位を細かくする傾向があるので、 環境 ✕ モジュール
分の上記が確保されてしまいます。
件のTerragruntプロジェクトをざっと見ると一部ディレクトリで 環境 5 * モジュール 10
程度はあったので、少なくとも 5 * 10 * 350MB = 17GB
ぐらいは重複したGoバイナリでディスクが埋められることになります。
肥大化した .terragrunt-cache
への対処方法
Terraformプラグイン類 (Goバイナリ) のキャッシュ位置をシステムで統一する
Terragrunt/Terraform 関係なく、そもそもバカデカいサイズのTerraformプラグインのバイナリをそれぞれのTerraform実行ディレクトリに置く必要がありません。
以下の設定を ~/.terraformrc
に書き、一回ダウンロードしたプラグインバイナリが再利用されるようにしましょう。
plugin_cache_dir = "$HOME/.terraform.d/plugin-cache"
参考: .terraformrc
のリファレンス
https://developer.hashicorp.com/terraform/cli/config/config-file
ただ、これを実行した後、 terragrunt run-all
などで複数のモジュールを一気に実行するとよくわからないエラーが出て実行に失敗することがありました。Terragrunt上での同時実行に弱いのかもしれません。
しかし現実的に言って、Terragrunt/Terraformを扱う上では設定は必須だと思います。そうじゃないとディスクがもったいなさすぎる。
.terragrunt-cache
ディレクトリを削除する
肥大化したキャッシュディレクトリが既にある場合は削除しましょう。
公式では以下の find
コマンド / TERRAGRUNT_DOWNLOAD
環境変数による方法が紹介されています。
# ディレクトリの確認
$ find . -type d -name ".terragrunt-cache"
# 削除
$ find . -type d -name ".terragrunt-cache" -prune -exec rm -rf {} \;
# あるいは TERRAGRUNT_DOWNLOAD でキャッシュの場所をあらかじめ固定しておいてたまにキャッシュを削除する
$ export TERRAGRUNT_DOWNLOAD=/Users/user/.my-terragrunt-cache-gonna-be-cleared-for-one-day
その他
Terragrunt がモジュールをコピーする範囲を減らす
あまりディスク利用量の削減には貢献しませんが、Terragruntがモジュールディレクトリをコピーする際のコストも毎回となるとそこそこ大きなものです。
たとえば、以下のように source = "..."
を記述している場合、本来必要な modA
だけではなく、その親の ../../../modules
自体のディレクトリが .terragrunt-cache
にコピーされます。
terraform {
source = "../../../modules//modA"
}
次のように source = "..."
に記述してある親ディレクトリを害の無い範囲で絞り込みます。無駄なコピーがなくなるので、実行時のパフォーマンスも向上します。
terraform {
# 修正後 - ../../../modules/modA をコピーする起点として / を参照する
source = "../../../modules/modA///"
# 修正前 - ../../../modules をコピーする起点として modA を参照する
# source = "../../../modules//modA"
}
ただし、この方法は source がリモートのgitリポジトリ等を参照している場合などは使えません。逆に、ローカルのディレクトリを参照している場合はほぼペナルティ無く実行できるのでオススメです。
まとめ
Terragrunt を使っていて何故かマシンのディスクが埋まってきていると通知を受ける場合は、一度Terragruntプロジェクトのデータサイズを確認したほうがいいでしょう。