みなさんこんにちは! 金融ソリューション事業部リースソリューション部の寺山です。本年から所属部署が変わりました。
今回は業務中に発見した 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 plan
や terraform apply
といった Terraform の実行は Terraform Cloud でホストされる仮想マシン内で実行されます。
Remote モードには以下のようなメリットがあります。
- GitHub 等の構成管理サービスと組み合わせて、インフラストラクチャに対する CI/CD パイプラインを容易に構築可能
- インフラストラクチャの操作権限は Terraform Cloud に設定すればよいため、AWS の IAM ユーザアクセスキーのような認証情報を作業者全員に配布することは不要となる
- インフラストラクチャに影響を及ぼす
terraform apply
も Terraform Cloud 上で実行されるため、操作証跡が集約される- Terraform およびProvider Pluginのバージョンの作業者間における差異を抑制できる
- 専用の UI が提供されており、特に
plan
やapply
コマンドの結果の視認性が優れている
また、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で説明されています。
実は .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.kazuhiro (Shodoで執筆されました)