Terraform Provider Plugin Cache を使ってください。
はじめに
皆様こんにちは、あかいけです。
ディスク容量を整理していたら、大量の.terraformフォルダを発掘してしまいました。
というわけで今回は、Provider Plugin Cacheでこの肥大化を抑える方法を検証してみます。
デカすぎる .terraform フォルダ
事の発端は、足りないディスク容量を整理していたときのことです。
.terraformフォルダの合計サイズを調べてみたら、とんでもない数字が出てきました。
find ~/work ~/github ~/project ~/Documents ~/deploy \
-type d -name .terraform -prune -print0 \
| xargs -0 du -sch | tail -1
81G total
81GB。
クラスメソッドに入社して1.5年ぐらい経過しましたが、この81GBはその歴史を物語っています。(おそらく)
1つ1つは数百MBでも、プロジェクトが積み重なればこうなってしまうわけですね。
応急処置
それはそうとディスクがもったいないので整理していきます。
.terraformを削除する
まずは、とりあえず消してスッキリさせます。
(.terraformフォルダはterraform initで再生成されるので、消してしまっても問題ありません)
find ~/work ~/github ~/project ~/Documents ~/deploy \
-type d -name .terraform -prune -exec rm -rf {} +
これで81GBが一気に解放されました。
恒久対策
前述の通りとりあえず81GBは解放されました。
ただし、このまま何もしなければ、1.5年後に同じ状態に戻ってしまいます。
そのため根本的な対策として、Provider Plugin Cacheを設定しておきましょう。
Provider Plugin Cache とは
Provider Plugin Cacheは、ダウンロード済みのプロバイダーバイナリを共有のキャッシュディレクトリに保管し、各作業ディレクトリからはそこへシンボリックリンクを張って参照する仕組みです。
同じバージョンのプロバイダーであれば実体は1つで済むため、プロジェクトごとにバイナリを重複して持つ必要がなくなります。
設定方法は、環境変数TF_PLUGIN_CACHE_DIRを使う方法と、CLI設定ファイル.terraformrcに書く方法の2通りがあります。
今回はどちらも試してみます。
事前準備:キャッシュを置くフォルダを作っておく
どちらの方法でも、キャッシュを保管するフォルダは事前に作っておく必要があります。
mkdir -p $HOME/.terraform.d/plugin-cache
設定しない場合
まずは比較のため、Plugin Cacheを設定していない状態での挙動を確認しておきます。
検証用のmain.tfは以下を使います。
AWSプロバイダーを指定して、S3バケットを1つ作るだけのシンプルな構成です。
terraform {
required_version = ">= 1.15.0"
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 6.0"
}
}
}
provider "aws" {
region = "ap-northeast-1"
}
resource "aws_s3_bucket" "example" {
bucket = "example-bucket"
}
この状態でterraform initします。
terraform init
Initializing the backend...
Initializing provider plugins...
- Reusing previous version of hashicorp/aws from the dependency lock file
- Using previously-installed hashicorp/aws v6.60.0
Terraform has been successfully initialized!
You may now begin working with Terraform. Try running "terraform plan" to see
any changes that are required for your infrastructure. All Terraform commands
should now work.
If you ever set or change modules or backend configuration for Terraform,
rerun this command to reinitialize your working directory. If you forget, other
commands will detect it and remind you to do so if necessary.
initが完了したので、.terraformフォルダのサイズを見てみます。
du -h
778M ./.terraform/providers/registry.terraform.io/hashicorp/aws/6.60.0/darwin_arm64
778M ./.terraform/providers/registry.terraform.io/hashicorp/aws/6.60.0
778M ./.terraform/providers/registry.terraform.io/hashicorp/aws
778M ./.terraform/providers/registry.terraform.io/hashicorp
778M ./.terraform/providers/registry.terraform.io
778M ./.terraform/providers
778M ./.terraform
778M .
AWSプロバイダー1つで778MBです。
これがプロジェクトごとにコピーされていくわけですね。
先ほどの81GBにも納得です。
環境変数の場合
では、環境変数TF_PLUGIN_CACHE_DIRでキャッシュ先を指定してみます。
export TF_PLUGIN_CACHE_DIR="$HOME/.terraform.d/plugin-cache"
main.tfは先ほどと同じものを使い、.terraformを削除した状態で改めてinitしてみます。
terraform init
Initializing the backend...
Initializing provider plugins...
- Finding hashicorp/aws versions matching "6.60.0"...
- Installing hashicorp/aws v6.60.0...
- Installed hashicorp/aws v6.60.0 (signed by HashiCorp)
Terraform has created a lock file .terraform.lock.hcl to record the provider
selections it made above. Include this file in your version control repository
so that Terraform can guarantee to make the same selections by default when
you run "terraform init" in the future.
Terraform has been successfully initialized!
You may now begin working with Terraform. Try running "terraform plan" to see
any changes that are required for your infrastructure. All Terraform commands
should now work.
If you ever set or change modules or backend configuration for Terraform,
rerun this command to reinitialize your working directory. If you forget, other
commands will detect it and remind you to do so if necessary.
init後の作業ディレクトリを見てみると、.terraformはほぼ空になっています。
du -h
0B ./.terraform/providers/registry.terraform.io/hashicorp/aws/6.60.0
0B ./.terraform/providers/registry.terraform.io/hashicorp/aws
0B ./.terraform/providers/registry.terraform.io/hashicorp
0B ./.terraform/providers/registry.terraform.io
0B ./.terraform/providers
0B ./.terraform
8.0K .
778MBが0Bになりました。
どういうことかというと、プロバイダーの実体がキャッシュ先に置かれ、作業ディレクトリからはそこへのシンボリックリンクになっているためです。
tree -a .terraform/
.terraform/
└── providers
└── registry.terraform.io
└── hashicorp
└── aws
└── 6.60.0
└── darwin_arm64 -> /Users/akaike.haruka/.terraform.d/plugin-cache/registry.terraform.io/hashicorp/aws/6.60.0/darwin_arm64
リンク先のキャッシュフォルダには、ちゃんとバイナリの実体が入っています。
tree -a ~/.terraform.d/
.terraform.d/
├── checkpoint_cache
├── checkpoint_signature
├── credentials.tfrc.json
└── plugin-cache
└── registry.terraform.io
└── hashicorp
└── aws
└── 6.60.0
└── darwin_arm64
├── LICENSE.txt
└── terraform-provider-aws_v6.60.0_x5
du -h ~/.terraform.d/
791M .terraform.d//plugin-cache/registry.terraform.io/hashicorp/aws/6.60.0/darwin_arm64
791M .terraform.d//plugin-cache/registry.terraform.io/hashicorp/aws/6.60.0
791M .terraform.d//plugin-cache/registry.terraform.io/hashicorp/aws
791M .terraform.d//plugin-cache/registry.terraform.io/hashicorp
791M .terraform.d//plugin-cache/registry.terraform.io
791M .terraform.d//plugin-cache
791M .terraform.d/
実体はキャッシュ側に1つ持つだけなので、以降このバージョンを使うプロジェクトが増えても、作業ディレクトリ側の容量は増えません。
.terraformrc の場合
環境変数ではなく、設定ファイル(.terraformrc)で指定することもできます。
シェルの設定に依存せず、常に有効にしておきたい場合はこちらがおすすめです。
$HOME直下に.terraformrcを作成し、plugin_cache_dirを指定します。
plugin_cache_dir = "$HOME/.terraform.d/plugin-cache"
こちらでもキャッシュが効くか確認します。
先ほどと同じバージョンだと違いが分かりにくいので、プロバイダーのバージョンを6.59.0に変えて試してみます。
terraform {
required_version = ">= 1.15.0"
required_providers {
aws = {
source = "hashicorp/aws"
version = "6.59.0"
}
}
}
provider "aws" {
region = "ap-northeast-1"
}
resource "aws_s3_bucket" "example" {
bucket = "example-bucket"
}
terraform init
Initializing the backend...
Initializing provider plugins...
- Finding hashicorp/aws versions matching "6.59.0"...
- Installing hashicorp/aws v6.59.0...
- Installed hashicorp/aws v6.59.0 (signed by HashiCorp)
Terraform has created a lock file .terraform.lock.hcl to record the provider
selections it made above. Include this file in your version control repository
so that Terraform can guarantee to make the same selections by default when
you run "terraform init" in the future.
Terraform has been successfully initialized!
You may now begin working with Terraform. Try running "terraform plan" to see
any changes that are required for your infrastructure. All Terraform commands
should now work.
If you ever set or change modules or backend configuration for Terraform,
rerun this command to reinitialize your working directory. If you forget, other
commands will detect it and remind you to do so if necessary.
.terraformrcでもちゃんとキャッシュが効いて、別バージョンをインストールできています。
作業ディレクトリ側は今回も0Bです。
du -h .
0B ./.terraform/providers/registry.terraform.io/hashicorp/aws/6.59.0
0B ./.terraform/providers/registry.terraform.io/hashicorp/aws
0B ./.terraform/providers/registry.terraform.io/hashicorp
0B ./.terraform/providers/registry.terraform.io
0B ./.terraform/providers
0B ./.terraform
8.0K .
キャッシュ先を見ると、6.59.0と6.60.0がバージョンごとにきれいにフォルダ分けされて共存しています。
レジストリ/名前空間/プロバイダー名/バージョン/プラットフォームという階層で整理されていくみたいですね。
美しい…。
tree -a ~/.terraform.d/
/Users/akaike.haruka/.terraform.d/
├── checkpoint_cache
├── checkpoint_signature
├── credentials.tfrc.json
└── plugin-cache
└── registry.terraform.io
└── hashicorp
└── aws
├── 6.59.0
│ └── darwin_arm64
│ ├── LICENSE.txt
│ └── terraform-provider-aws_v6.59.0_x5
└── 6.60.0
└── darwin_arm64
├── LICENSE.txt
└── terraform-provider-aws_v6.60.0_x5
du -h ~/.terraform.d/
791M /Users/akaike.haruka/.terraform.d//plugin-cache/registry.terraform.io/hashicorp/aws/6.60.0/darwin_arm64
791M /Users/akaike.haruka/.terraform.d//plugin-cache/registry.terraform.io/hashicorp/aws/6.60.0
791M /Users/akaike.haruka/.terraform.d//plugin-cache/registry.terraform.io/hashicorp/aws/6.59.0/darwin_arm64
791M /Users/akaike.haruka/.terraform.d//plugin-cache/registry.terraform.io/hashicorp/aws/6.59.0
1.5G /Users/akaike.haruka/.terraform.d//plugin-cache/registry.terraform.io/hashicorp/aws
1.5G /Users/akaike.haruka/.terraform.d//plugin-cache/registry.terraform.io/hashicorp
1.5G /Users/akaike.haruka/.terraform.d//plugin-cache/registry.terraform.io
1.5G /Users/akaike.haruka/.terraform.d//plugin-cache
1.5G /Users/akaike.haruka/.terraform.d/
バージョン違いはさすがに別実体としてキャッシュされるので、こちらは1.5GBに増えています。
とはいえ、同じバージョンを使うプロジェクトがいくつあってもキャッシュ側は1つで済むので、プロジェクトが増えるほど効果は大きくなります。
さいごに
以上、Terraform Provider Plugin Cacheを使ってディスク容量を節約する話でした。
.terraformフォルダの肥大化は、地味ですがボディブローのようにじわじわとディスクを圧迫してきます。
Provider Plugin Cacheを設定しておけば、同じバージョンのプロバイダーを何度もダウンロードせずに済み、作業ディレクトリ側の容量もほぼゼロに抑えられます。
設定自体も環境変数か.terraformrcに1行足すだけなので、とりあえず入れておいて損はないかと思います。
これからTerraformを使い始める方はもちろん、すでにバリバリ使っている方も、まだ設定していないならぜひ Provider Plugin Cache を使ってみてください。





