BioErrorLog Tech Blog

試行錯誤の記録

terraform plan結果の要約を表示するワンライナー

terraform plan実行時に、plan結果と要約を併せて表示するワンライナーを組みます。

はじめに

terraform plan結果は往々にして長くなってしまい、全てチェックするのが辛くなりがちです。

plan結果の出力を簡潔にするようなコマンドオプションも現段階では提供されていません: concise mode for `terraform plan` · Issue #10507 · hashicorp/terraform · GitHub

そこで今回は、terraform plan結果を要約して表示するワンライナーを組んでいきます。

もっとマシなやり方がある場合はぜひ教えてください。

terraform plan結果の要約を表示する

シンプルな解決策から順に複雑なものに発展させていきます。

※作業環境:

terraform --version
# Terraform v1.3.4
# on linux_amd64

lsb_release -a
# Distributor ID:  Ubuntu
# Description: Ubuntu 22.04.1 LTS
# Release: 22.04
# Codename:    jammy

1. とりあえずgrep

terraform plan | grep -E '#|Plan:'

plan結果のうち、要点となる情報が含まれる#と最終行のPlan: XX to add, X to change, X to destroy.を抽出します。

要点だけ見たいときはこれでも十分使えますね。


出力例:

$ terraform plan | grep -E '#|Plan:'
  # module.lambda_rust.data.archive_file.zip will be read during apply
  # (depends on a resource or a module with changes pending)
  # module.lambda_rust.aws_cloudwatch_event_rule.this[0] will be created
  # module.lambda_rust.aws_cloudwatch_event_target.this[0] will be created
  # module.lambda_rust.aws_cloudwatch_log_group.this will be created
  # module.lambda_rust.aws_iam_policy.lambda_logging will be created
  # module.lambda_rust.aws_iam_policy.trigger_lambda will be created
  # module.lambda_rust.aws_iam_role.this will be created
  # module.lambda_rust.aws_iam_role_policy_attachment.this["demo_lambda_logging"] will be created
  # module.lambda_rust.aws_lambda_function.this will be created
  # module.lambda_rust.aws_lambda_permission.allow_cloudwatch[0] will be created
  # module.lambda_rust.null_resource.rust_build will be created
Plan: 10 to add, 0 to change, 0 to destroy.

2. 元々の出力も表示する

上のやり方だと元々の詳細な出力は見れません。 要約表示と元の出力の両方を見たいところです。

とりあえずteeで出力を分岐させ、プロセス置換を利用してgrep要約を適当なtmpファイルに出力させて表示してみます:

terraform plan | tee >(grep -E '#|Plan:' > /tmp/_plan_abst.log) && cat /tmp/_plan_abst.log

これで、plan実行したときはまず従来の結果を出力し、処理が終了したら要約が表示されるようになります。


出力例:

$ terraform plan | tee >(grep -E '#|Plan:' > /tmp/_plan_abst.log) && cat /tmp/_plan_abst.log

## 中略:従来のplan結果表示

  # module.lambda_rust.null_resource.rust_build will be created
  + resource "null_resource" "rust_build" {
      + id       = (known after apply)
      + triggers = {
          + "code_diff" = ""
        }
    }

Plan: 10 to add, 0 to change, 0 to destroy.

─────────────────────────────────────────────────────────────────────────────

Note: You didn't use the -out option to save this plan, so Terraform can't
guarantee to take exactly these actions if you run "terraform apply" now.
  # module.lambda_rust.data.archive_file.zip will be read during apply
  # (depends on a resource or a module with changes pending)
  # module.lambda_rust.aws_cloudwatch_event_rule.this[0] will be created
  # module.lambda_rust.aws_cloudwatch_event_target.this[0] will be created
  # module.lambda_rust.aws_cloudwatch_log_group.this will be created
  # module.lambda_rust.aws_iam_policy.lambda_logging will be created
  # module.lambda_rust.aws_iam_policy.trigger_lambda will be created
  # module.lambda_rust.aws_iam_role.this will be created
  # module.lambda_rust.aws_iam_role_policy_attachment.this["demo_lambda_logging"] will be created
  # module.lambda_rust.aws_lambda_function.this will be created
  # module.lambda_rust.aws_lambda_permission.allow_cloudwatch[0] will be created
  # module.lambda_rust.null_resource.rust_build will be created
Plan: 10 to add, 0 to change, 0 to destroy.

3. 一時ファイルの作成にmktempを使う

teeで出力を分岐させ、プロセス置換を利用してgrep要約を適当なtmpファイルに出力させて表示してみます。

上ではこのようにしましたが、"適当なtmpファイル"を自分で指定するのも歯がゆいのでmktempコマンドで一時ファイルを作成させてみます:

tf_result_temp=$(mktemp); terraform plan | tee >(grep -E '#|Plan:' > ${tf_result_temp}) && cat ${tf_result_temp}

mktempコマンドはデフォルトで/tmp配下にファイルを作成するので、tmpファイルがplan実行毎に作成されることは気にしていません(/tmp配下のファイルは自動削除される)。

もしファイルが続々と作成されることが気に食わない場合は、最後にtmpファイルの削除を入れ込んでも良いかもしれません:

tf_result_temp=$(mktemp); terraform plan | tee >(grep -E '#|Plan:' > ${tf_result_temp}) && cat ${tf_result_temp} && rm ${tf_result_temp}


この方法での出力は、上記の "2. 元々の出力も表示する" と同じです。

おまけ: aliasを作成する

上に挙げたコマンドはどれも長くて手打ちは面倒なので、aliasを作成すると便利です。

私はこんな感じでterraformコマンドのaliasを運用しています。

alias tt='terraform'
alias ttp='terraform plan'
alias ttpp='tf_result_temp=$(mktemp); terraform plan | tee >(grep -E "#|Plan:" > ${tf_result_temp}) && cat ${tf_result_temp}'
alias tta='terraform apply'
alias ttm='terraform fmt -recursive'

dotfiles/.bash_aliases at main · bioerrorlog/dotfiles · GitHub

おわりに

terraform plan結果を要約して表示するワンライナーを組みました。

もっと良いのを思いついたらまた更新しようと思います。

[関連記事]

www.bioerrorlog.work

www.bioerrorlog.work

www.bioerrorlog.work

参考

concise mode for `terraform plan` · Issue #10507 · hashicorp/terraform · GitHub

Man page of MKTEMP

GitHub - bioerrorlog/terraform-examples: My terraform example projects.