tfcmt で Terraform の CI/CD を改善する
Terraform の CI/CD を改善する tfcmt というツールを紹介します。
ちなみに HashiTalks JP 2021 でも紹介しています。
執筆時点で最新バージョンは以下のとおりです。
- tfcmt: v3.0.0
- github-comment: v4.0.1
- tfnotify: v0.7.0
tfcmt は terraform plan, apply の結果を GitHub の Pull Request (以下 PR) にコメントとして通知する CLI ツールです。
態々 CI のログを見にいかなくても PR のページで結果を確認でき、
なおかつ素のログに比べて非常に分かりやすいのが特徴です。
tfnotify の Fork ですが、互換性はありません。
自分にとって不要な機能(主に GitHub 以外への通知)を削る代わりに、様々な改善を入れています。
GitHub 以外に通知したい方には tfcmt は合いません。
tfcmt によるコメントのスクリーンショットは断りのない限りデフォルト設定によるものです。
設定ファイル無しでも十分いい感じのコメントがされるのが分かるかと思います。
terraform plan の結果ですが、以下のことがぱっとわかります。
- リソース削除の警告
- 作成・更新・削除されるリソースの数
- 変更されるリソースのアドレス
plan の結果に応じて色付けされた label が PR に付与されます。
- 緑: リソースの変更なし
- 青: リソースが追加・更新される
- 赤: リソースが削除される
そのため、コメントを見なくても label を見るだけで大まかな内容が視覚的に分かるようになっています。
label は検索でも役に立ちます。
plan の詳細な結果はシンタックスハイライトされています。
Refreshing state などのログも除外され、コンパクトになっています。
Terraform v0.15.4 から、 Terraform 以外のリソースの変更が terraform plan のログに含まれるようになりました。
これは便利ではありますが、同時に terraform plan の結果をとても分かりづらくしていると思います(特にこの機能のことを知らない人にとっては)。
そこで tfcmt では Terraform 以外のリソースの変更を分離して分かりやすくしています。
terraform plan の warning も分かりやすく、気づかずに放置されることもないでしょう。
ところで、複数の working directory で terraform plan を実行している場合、コメントと working directory の対応がわからなくなってしまいます。
そこで tfcmt では -var target:<working directory 名>
といったパラメータを渡すことで、対応がわかるようにできます。
$ tfcmt -var target:foo plan -- terraform plan
label にも target が prefix としてつくので、区別が付きます。
github-comment による古いコメントの非表示
PR のコメントで通知するやり方だと、コメント欄が荒れてしまうのが難点です。
tfcmt では github-comment という別のツールと組み合わせることで、古いコメントを非表示にできます。
github-comment は GitHub の commit, issue, PR にコメントをする CLI ツールですが、 tfcmt と同様にコメント欄が荒れてしまう問題があります。
そこで github-comment には条件にマッチしたコメントを非表示にする github-comment hide
というコマンドがあります。
$ github-comment hide
特定の文字列を含んだコメントなどを対象にすることも出来ますが、
独自のフォーマットでコメントにメタデータを埋め込み、そのメタデータに基づいてコメントを非表示にすることも出来ます。
メタデータとしては commit の SHA や CI の build ID, workflow name のようなものや、任意のデータを埋め込むことが出来ます。
メタデータは以下のような HTML のコメントとしてコメントに埋め込まれるため、見た目上は何も変わりません(コメントを編集状態にすると確認できます)。
<!-- github-comment: {"Command":"plan","JobName":"build","PRNumber":158,"Program":"tfcmt","SHA1":"a92fb1cbe843eaca58390bf8f69f0bad3ce3d125","Target":"foo","Vars":{},"WorkflowName":"screen shot"} -->
tfcmt はこのメタデータに対応しており、コメントをする際にメタデータを埋め込むので、 github-comment でメタデータを使ってコメントを非表示に出来ます。
tfnotify は古いコメントを削除することがある
tfcmt と違い、 tfnotify は条件にマッチした古いコメントを(非表示ではなく)削除します。
この挙動はドキュメント化されていませんが、バグなどではなく明らかに意図的に削除しているように見受けられます。
個人的にはこの挙動は望ましくなかったので、 tfcmt ではコメントを削除はせず上記のような変更を行っています。
Tips: apply 失敗時にメンションする
terraform plan に成功したのに、マージしたら apply に失敗するというのはよくあることだと思います。
Zero Config ではなくなってしまいますが、 tfcmt では apply に失敗した際に PR の author などに mention をして気づきやすくすることが出来ます
(GitHub でメンションされたら Slack などのチャットツールに通知が来るようにしておけばより気づきやすいでしょう)。
以下に例を示します。
templates:
guide_apply_failure: |
@{{.Vars.author}} Please check the error.
guide_apply_parse_error: |
@{{.Vars.author}} Please check the error.
$ tfcmt -var "author:octocat" apply -- terraform apply -auto-approve
Install
Go 製なので簡単に install 出来ます。
- Homebrew:
brew install suzuki-shunsuke/tfcmt/tfcmt
- aqua
- GitHub Releases
個人的には aqua を使ってバージョン管理をするのがオススメです。
使い方
GitHub にコメントするために環境変数 GITHUB_TOKEN
に Access Token を設定する必要があります。
$ export GITHUB_TOKEN=xxx
terraform plan
, terraform apply
を以下のように置き換えます。
$ tfcmt plan -- terraform plan [terraform plan の引数...]
$ tfcmt apply -- terraform apply [terraform apply の引数...]
設定ファイルはなくても動きますが、 tfcmt.yaml
という設定ファイルで設定することもできます。
tfnotify からの改善点
他にもありますが、ざっと以下のような改善を行っています。
- 設定ファイル無しで動く
- PR Label を plan の結果に応じて色付きで設定
- コメントのテンプレートの改善
- Terraform >= v0.15 のサポート
- tfnotify は正常に動かないという認識ですが、そういう声を聞かない(issue もない)のが不思議
- github-comment との連携による古いコメントの非表示
- API の変更 (pipe からサブコマンド方式への変更)
- 細かな改良
- 設定ファイルをカレントディレクトリからルートディレクトリに向かって再帰的に探索(Monorepo で設定ファイルを共有しやすい)
- sprig をサポート
- コマンドラインオプションでパラメータを渡せる
- plan の結果のパースに失敗してもコメントする
- label を無駄に再設定しない
- label の更新に失敗してもコメントする
-
--version
,version
コマンドのサポート
さいごに
Terraform の CI/CD の Developer Experience を大幅に改善する tfcmt という CLI ツールを紹介しました。
詳細についてはドキュメントやリリースノートを読んでください。
Discussion