電通総研 テックブログ

電通総研が運営する技術ブログ

terraformignoreの仕様にハマりながらローカルplan時間を大幅に短縮した

みなさんこんにちは! 金融ソリューション事業部リースソリューション部の寺山です。本年から所属部署が変わりました。
今回は業務中に発見した Terraform の Tips を紹介する短めの記事となります。

先に結論

タイトルを先に回収しますと、ローカル plan 時間が大幅に改善された .terraformignore は以下です。

# ignore all
**
# include terraform
!code/terraform/
# ignore .terraform
code/terraform/**/.terraform/

以降のセクションでは背景等を含めて詳細を解説します。

Terraform CloudのRemoteモードについて

弊社の金融ソリューション事業部はM5という Java 製マイクロサービスフレームワークを製品開発し、お客様のシステムや自社サービス/パッケージの開発に活用しております。私は、この M5 をホストするためのインフラ構成の検討や、その実装方法(主に IaC の開発)に従事しています。

IaC 化ツールとして HashiCorp 社のTerraform、および、同社の SaaS であるTerraform Cloudを利用しています。

Terraform Cloud の Workspace の設定にはExecution Modeというものがあります。この設定で Remote を選択すると、terraform planterraform apply といった Terraform の実行は Terraform Cloud でホストされる仮想マシン内で実行されます。

Remote モードには以下のようなメリットがあります。

  • GitHub 等の構成管理サービスと組み合わせて、インフラストラクチャに対する CI/CD パイプラインを容易に構築可能
  • インフラストラクチャの操作権限は Terraform Cloud に設定すればよいため、AWS の IAM ユーザアクセスキーのような認証情報を作業者全員に配布することは不要となる
  • インフラストラクチャに影響を及ぼす terraform apply も Terraform Cloud 上で実行されるため、操作証跡が集約される
    • Terraform およびProvider Pluginのバージョンの作業者間における差異を抑制できる
  • 専用の UI が提供されており、特に planapply コマンドの結果の視認性が優れている

また、Remote モードではローカルで実行した terraform plan も Terraform Cloud 上で実行されます。タイトルの「ローカル plan」とはこのオペレーションのことを指しています。

Remoteモード時のローカルplan時間の課題

前述のようにメリットが多い Terraform Cloud の Remote モードですが、実は課題に感じている点がありました。

ローカルで plan 時は、ローカルのファイルシステムにあるリポジトリルートディレクトリを起点として全ファイルが Terraform Cloud に送信されます。送信されたソースコードを基に環境が構築され、plan が実行される仕組みです。
このローカル plan を実行には、毎回 10 分ほど要していました。

$ time terraform plan
# (省略)
terraform plan  94.39s user 8.39s system 18% cpu 9:21.40 total

plan は頻繁に実行するコマンドであるため、毎回 10 分待たされるのは生産性に影響が出てしまいます。
Remote モードではなく Local に変更するか、Terraform Cloud の利用を停止するかを検討していました。

解決方法と私がハマったポイント

本件の解決方法は冒頭のセクションに記載したとおり .terraformignore ファイルを利用することです。
.terraformignore.gitignore に類似した仕組みで、当該ファイルに記述したファイルやディレクトリを Terraform Cloud に送信する対象外とします。

このファイルの仕様はExcluding Files from Upload with .terraformignoreで説明されています。

  1. .gitignore に類似した仕組みではあるもののリポジトリのルートディレクトリ以外では機能しない
  2. デフォルトで .git.terraform ディレクトリが除外される

実は .terraformignore のことは以前から認識しており利用していました。当該リポジトリは monorepo として運用しており、Terraform の IaC 化コードの他に node_modules のような容量が大きいディレクトリも存在していました。
Terraform のディレクトリ以外を .terraformignore に記述することでローカル plan 時間が改善されることを期待していたのですが、前述した plan 時間は .terraformignore 配置後のものでした。

この頃に指定していた内容は以下です。

# ignore all
**
# include terraform
!code/terraform/

1 行目の記述でリポジトリ内の全ファイルを除外した上で、Terraform の IaC 化コードが配置されたディレクトリのみは Terraform Cloud に送信されるように ! を付与しています。
前述したように monorepo 運用している背景から、今後もディレクトリが増えたとしても、このファイルをメンテナンスする必要がないようホワイトリスト形式にしたいという意図です。

TF_IGNORE環境変数trace を指定し、除外されたファイルを表示して確認すると以下のような出力となります。

$ terraform plan
#(省略)
Skipping excluded path: .git
Skipping excluded path: .git/COMMIT_EDITMSG
Skipping excluded path: .git/FETCH_HEAD
#(省略)
Skipping excluded path: code/shell/aws/sts/set-sts-profile.sh
Skipping excluded path: code/terraform
Skipping excluded path: doc
#(省略)
Skipping excluded path: doc/node_modules
Skipping excluded path: doc/node_modules/.bin
Skipping excluded path: doc/node_modules/.bin/acorn
#(省略)

一見、記述の意図したとおり除外できているように見えます。
しかしながら、デフォルトで除外されている .terraform は Terraform Cloud に送信されてしまっていたため、ローカル plan 時間が長くなっていたとわかりました。

.terraform ディレクトリには terraform init 時にProvider Pluginがダウンロードされます。このプラグインが数百 MB の容量のため、送信に時間を要します。

$ du -h .terraform 
369M    .terraform/providers/registry.terraform.io/hashicorp/aws/4.52.0/darwin_amd64
369M    .terraform/providers/registry.terraform.io/hashicorp/aws/4.52.0
369M    .terraform/providers/registry.terraform.io/hashicorp/aws
 14M    .terraform/providers/registry.terraform.io/hashicorp/random/3.3.2/darwin_amd64
 14M    .terraform/providers/registry.terraform.io/hashicorp/random/3.3.2
 13M    .terraform/providers/registry.terraform.io/hashicorp/random/3.4.3/darwin_amd64
 13M    .terraform/providers/registry.terraform.io/hashicorp/random/3.4.3
 28M    .terraform/providers/registry.terraform.io/hashicorp/random
397M    .terraform/providers/registry.terraform.io/hashicorp
397M    .terraform/providers/registry.terraform.io
397M    .terraform/providers
4.0K    .terraform/modules
397M    .terraform

したがって、私のようにホワイトリスト風な記述をする場合は、.terraform ディレクトリを明示的に指定する必要があります。

# ignore all
**
# include terraform
!code/terraform/
# ignore .terraform
code/terraform/**/.terraform/ ##←これ

.terraformignore に追加後はローカル plan 時間が 1 分ほどとなり、大幅に短縮されました!

$ time terraform plan
# (省略)
Skipping excluded path: code/shell/aws/sts/set-sts-profile.sh
Skipping excluded path: code/terraform
Skipping excluded path: code/terraform/aws/excluded/.terraform/
Skipping excluded path: code/terraform/aws/excluded/.terraform/environment
Skipping excluded path: code/terraform/aws/excluded/.terraform/providers
Skipping excluded path: code/terraform/aws/excluded/.terraform/providers/registry.terraform.io
Skipping excluded path: code/terraform/aws/excluded/.terraform/providers/registry.terraform.io/hashicorp
Skipping excluded path: code/terraform/aws/excluded/.terraform/providers/registry.terraform.io/hashicorp/aws
Skipping excluded path: code/terraform/aws/excluded/.terraform/providers/registry.terraform.io/hashicorp/aws/4.52.0
Skipping excluded path: code/terraform/aws/excluded/.terraform/providers/registry.terraform.io/hashicorp/aws/4.52.0/darwin_amd64
Skipping excluded path: code/terraform/aws/excluded/.terraform/providers/registry.terraform.io/hashicorp/aws/4.52.0/darwin_amd64/terraform-provider-aws_v4.52.0_x5
# (省略)
terraform plan  6.07s user 0.58s system 11% cpu 58.623 total

1 分ほどであれば生産性への影響は許容範囲であると評価しており、Terraform Cloud の Remote モードの利用を継続することにネガティブな要素はなくなりました。

なお、ブラックリスト形式で除外したいパスを丁寧に記述すれば、Terraform のドキュメントに記載のとおりデフォルトで .git.terraform ディレクトリは除外されます。

同じような境遇の方のご参考になれば幸いです! 最後までお読みいただきありがとうとございました。

注意点

ローカル plan の所要時間は、Terraform の IaC 化コードのファイルサイズやネットワーク帯域・通信品質に依存するため、同じ効果が得られるとはお約束できないこと、ご留意ください。


私たちは一緒に働いてくれる仲間を募集しています!

金融機関のようなお客様においてもクラウドファーストやマイクロサービスのようなモダンな技術の採用が進みつつあります。ご自身のインフラ/クラウドスキルをエンタープライズ領域でも活用したい・挑戦したいという方がいらっしゃいましたら、ぜひご応募ください!

金融システム インフラ・アーキテクト 金融システム インフラエンジニア

執筆:寺山 輝 (@terayama.akira)、レビュー:@mizuno.kazuhiroShodoで執筆されました