CIでTerraformを操作しようと思うと、以前ではTerraform Cloud一択でした。しかし2023年5月、料金プランが変更され、5ユーザーまで無料だったものが、500リソースまで無料になってしまいました。PoCなどで使っていた私としましてはなかなかの痛手です。そこで、CI環境をTerraform CloudからGitHub Actionsへ乗り換えを考えた時に、Planの内容をPRにコメントできたら便利だなぁっと思い色々検索してみたところterraform-j2mdというツールがヒットしました。
terraform-j2md
terraform planの内容をMarkdownに変換してくれるツールです。機能としてはただそれだけなのですが、1つのことをいい感じに扱いつつ、stdin/outでデータを処理できて連携しやすいなど、UNIX哲学的で大変美しいと感じました。
試す
まずはローカルで試してみます。インストール方法はこちら
go install github.com/reproio/terraform-j2md/cmd/terraform-j2md@latest
Goの設定(GOPATHなど)を何もしていなければ~/go/bin以下にインストールされていると思います。
$ ~/go/bin/terraform-j2md -help
Usage of /path/to/home/go/bin/terraform-j2md:
-no-escape-html
prevent <, >, and & from being escaped in JSON strings
オプションはこれしかありません。
さっそくMarkdown化してみます。
$ terraform plan -out plan.tfplan $ terraform show -json plan.tfplan | ~/go/bin/terraform-j2md
terraform plan -out plan.tfplanでplanの結果をplan.tfplanというファイルに出力しています。なぜこんなことをしているのかというと、terraform-j2mdはJSON形式の値を標準入力から受け取ってMarkdownに変換するのですが、planは出力をJSONフォーマットに変更できません。そこで、planの内容を一度plan.tfplanファイルに保存しておいて、terraform showでJSONフォーマットに変換しています。この値をterraform-j2mdに渡してあげると・・・
### 1 to add, 0 to change, 0 to destroy, 0 to replace.
- add
- random_id.this
<details><summary>Change details</summary>
````````diff
# random_id.this will be created
@@ -1,2 +1,6 @@
-null
+{
+ "byte_length": 8,
+ "keepers": null,
+ "prefix": null
+}
````````
</details>
Markdown化できました。
次はGitHub Actionsで試してみます。
実際に試したリポジトリはこちら
GitHub Actionsだからと言ってもやってることは同じです。
43,44行目でplan.tfplanファイルを作成し、46,47行目でghコマンドを使用してPRにコメントしています。46行目はghコマンドに--edit-lastオプションを指定して、同じAuthorでコメントが存在していた場合は、コメントを上書きします。しかし、コメントが存在しない場合にエラーが出てしまうので、47行目でエラー時に--edit-lastを外してコメントし直しています。こちらのIssueを参考に実装しました。
動いた画面はこちら

planの内容がPRから確認できました。
まとめ
Terraform Cloudの代用にGitHub Actionsを使ってみました。Applyをどうするかが少し悩みどころではありますが、planまでなら不便なく使えそうです。 terraform-j2mdではなくてtfactionというGitHub Actionsでいい感じにTerraformの運用ができるものもあるようなので、こちらもその内使ってみようと思います。
