Terraform Cloudでローカルからの「terraform plan」が遅い場合は.terraformignoreを活用しよう

.terraformignoreで不要なファイルを除外して快適なローカル開発を!
2021.05.31

はじめに

CX事業本部の佐藤智樹です。

今回は表題の通りTerraform Cloudを使っていてterraform planが遅くなっている方向けの記事です。

対象としては表題だけだとピンポイントな内容ですが、もしTerraform Cloudを使っている方ならサービスが少し大きくなったときに必ず当たる問題だと思うのでご一読ください。

念のため検証も行っているので良ければ最後まで読んでください。

結論

.terraformignoreファイルを作成して、Terraformと関係ないファイルを中で指定してください。

.terraformignore とは

詳細は以下のTerraform Cloudに関するドキュメントの「Excluding Files from Upload with .terraformignore」に書かれています。

Terraform Cloud に stateファイルを置く場合、ローカルからも plan による差分確認が行えるよう設定ができます。この操作ではリポジトリにあるローカルのすべてのファイルがアップロードされるため、もしTerraformと関係のないファイルが大量にあるリポジトリの場合に plan の確認に大幅に時間がかかります。

例えば、モノレポ構成にしていてWebアプリケーションのコードが同じリポジトリに配置している場合に発生します。(というより筆者の場合上記の時に発生しました)

対処するためには.gitignoreファイルなどと同じようにアップロードして欲しくないファイルを指定する必要があります。次章からは念のため本当に動作するのか検証してみます。

検証

検証自体は以下の流れで進めます。

  1. Terraform Cloudから plan 実行できる環境を準備
  2. ローカルからplan の実行時間を計測
  3. Terraformと無関係の大容量ファイルをリポジトリに追加
  4. ローカルからplan の実行時間を計測
  5. `.terraformignore`に3.で追加したファイルを無視するよう設定
  6. ローカルからplan の実行時間を計測

ファイルのアップロード時間に関係する内容なのでネットワークの接続状況などによってかなり変動します。なのであくまで参考程度にご確認ください。

1. Terraform Cloudから plan 実行できる環境を準備

まずはTerraform Cloud を実行できる環境を準備します。詳細な準備については以下の公式ドキュメントや弊社のブログをご確認ください。

以下のようにTerraform Cloudからplanやapply実行ができる環境を準備します。(※今回は検証のため簡易な設定にしていますが本来はアクセスキーやシークレットキーよりロールと外部IDの使用を推奨します。)

Terraform のコードは以下になります。

main.tf

terraform {
  backend "remote" {
    hostname     = "app.terraform.io"
    organization = "hogefuga-terraform"

    workspaces {
      name = "terraform_cloud_test"
    }
  }
}
provider "aws" {
  access_key = var.aws_access_key
  secret_key = var.aws_secret_key
  region = "ap-northeast-1"
}


resource "aws_vpc" "test-vpc" {
  cidr_block           = "10.0.0.0/16"
}

variables.tf

variable "aws_access_key" {
  type        = string
}

variable "aws_secret_key" {
  type        = string
}

後は Terraform Cloud 上の Variables に設定を追加すればAWS環境へのアクセス準備が完了します。

2. ローカルからplan の実行時間を計測

準備ができたのでローカルから plan を実行します。今回は計測のため timeコマンドを使用します。

% time terraform plan
~省略~
No changes. Your infrastructure matches the configuration.

Your configuration already matches the changes detected above. If you'd like
to update the Terraform state to match, create and apply a refresh-only plan.
terraform plan  0.93s user 0.56s system 3% cpu 41.642 total

大体コマンドを実行してコンソール上に結果が返ってくるまで40秒程度です。

3. Terraformと無関係の大容量ファイルをリポジトリに追加

次に不要な大容量ファイルを追加してみます。testディレクトリ配下にmkfileコマンドで100MB程度のファイルを5つ生成します。

% mkdir test      
% cd test 
% mkfile 100m dummyfile
% mkfile 100m dummyfile2
% mkfile 100m dummyfile3
% mkfile 100m dummyfile4
% mkfile 100m dummyfile5
% ls -l
total 1024000
-rw-------  1 sato.tomoki  hoge  104857600  5 30 17:12 dummyfile
-rw-------  1 sato.tomoki  hoge  104857600  5 30 17:15 dummyfile2
-rw-------  1 sato.tomoki  hoge  104857600  5 30 17:15 dummyfile3
-rw-------  1 sato.tomoki  hoge  104857600  5 30 17:15 dummyfile4
-rw-------  1 sato.tomoki  hoge  104857600  5 30 17:15 dummyfile5

上記のファイルをリポジトリに追加しておきます。

% git add test/*
% git commit -m "add dummy files"
% git push

4. ローカルからplan の実行時間を計測

ファイルを追加して遅くなるのか確認します。

% time terraform plan
~省略~
No changes. Your infrastructure matches the configuration.

Your configuration already matches the changes detected above. If you'd like
to update the Terraform state to match, create and apply a refresh-only plan.
terraform plan  2.29s user 0.75s system 3% cpu 1:23.96 total

1分20秒程度と目に見えて遅くなり始めました。

5. .terraformignoreに3.で追加したファイルを無視するよう設定

.terraformignoreファイルを追加してファイルを無視するよう設定します。

.terraformignore

test/

6. ローカルからplan の実行時間を計測

最後にローカルから実行して計測します。

% time terraform plan
~省略~
No changes. Your infrastructure matches the configuration.

Your configuration already matches the changes detected above. If you'd like
to update the Terraform state to match, create and apply a refresh-only plan.
terraform plan  0.90s user 0.63s system 3% cpu 46.043 total

45秒前後なので.terraformignoreの効果が30~40秒程度あることが確認できます。

所感

検証結果だと500MBで30秒程度の差分でしたが、担当しているPJではソースが大きくなったためか数十分ほど待たないと plan の結果が返ってこないという悲惨な状況だったのでどなたかの役に立てばと思い記事にしました。どなたかのお役に立てば幸いです。