🐷

Terraform公式スタイルガイドに沿ったpre-commitフックの活用

2024/04/08に公開

概要

先般 Terraform のスタイルガイドが公開されました。

https://developer.hashicorp.com/terraform/language/style

Run terraform fmt and terraform validate before committing your code to version control.

上記の通り、コードをバージョン管理(Gitなど)にコミットする前には terraform fmtterraform validate を実行することが推奨されています。

普段 Node.js で開発をしていますが、 husky + lint-staged でフォーマッターやリンターを自動実行するのが一般的です。
このような体験を Terraform でも実現したいと考え、pre-commit フックを用いて terraform fmtterraform validate を自動実行する方法を試行しました。

pre-commit のインストール

pre-commit は Python 製のツールで、terraform fmtterraform validate などのコマンドを Git コミット時に自動実行するためのフックを提供しています。

https://pre-commit.com/

まずは Python の実行環境を準備します。
システムにビルトインで組み込まれている Python や、pyenv、Rye などが利用できます。

https://rye-up.com/

Pythonの実行環境が用意できたら以下のコマンドで pre-commit をインストールします。

$ pip install pre-commit

pre-commit の設定

プロジェクトのルートに .pre-commit-config.yaml というファイルを設置します。
内容は以下にします。

.pre-commit-config.yaml
repos:
  - repo: https://github.com/antonbabenko/pre-commit-terraform
    rev: v1.88.4
    hooks:
      - id: terraform_fmt
        files: \.tf$
      - id: terraform_validate
        files: \.tf$

この .pre-commit-config.yaml ファイルは、 pre-commit フックの設定を定義しています。
YAMLの各フィールドをざっと説明します。

  • repos: このセクションでは、使用するリポジトリのリストを定義します。
    • repo: pre-commit-terraform の GitHub リポジトリの URL を指定します。このリポジトリには、Terraform に関連する pre-commit フックが含まれています。
    • rev: 使用する pre-commit-terraform のバージョンを指定します。この例では、バージョン v1.88.4 を使用しています。
    • hooks: このセクションでは、具体的にどのフックを使用するかを定義します。
      • id: terraform fmt コマンドを実行するフックを "terraform_fmt" で、 terraform validate を実行するフックは "terraform_validate" でそれぞれ指定しています。
      • files: フックが適用されるファイルのパターンを指定します。この例では、拡張子が .tf のファイルにのみフックが適用されます。

pre-commit install

前節で作成した設定を実際に動作させるには以下のコマンドを実行する必要があります。

$ pre-commit install

これでコミット時に terraform fmtterraform validate コマンドが自動的に実行され、Terraform ファイルのフォーマットと構文チェックが行われるようになります。

使用例

フォーマットを修正する必要がある場合をシミュレートするために、意図的にスペースのアライメントをずらした terraform.tf というファイルを追加します。
その状態でコミットを試みると、以下のような結果が得られます。

$ git commit -m 'Add terraform.tf'
Terraform fmt............................................................Failed
- hook id: terraform_fmt
- files were modified by this hook

terraform.tf

Terraform validate.......................................................Passed

この場合、 terraform fmt フックの実行結果は "Failed" となり、コミットは中断されます。
フォーマットがかかった結果として差分が出るので、この修正を git add でステージングに追加してから再度コミットする必要があります。

terraform-s3-eventbridge (add-providers)🔥 via 💠 default on ☁️  (ap-northeast-1) took 6s 
$ git diff                                               
diff --git a/terraform.tf b/terraform.tf
index ab8fcc7..81b54b7 100644
--- a/terraform.tf
+++ b/terraform.tf
@@ -3,7 +3,7 @@ terraform {
 
   required_providers {
     aws = {
-      source = "hashicorp/aws"
+      source  = "hashicorp/aws"
       version = "5.40"
     }
   }

terraform validate が "Failed" の場合はコミット中断が妥当だと思いますが、 terraform fmt が "Failed" になったあと毎回再度コミットするのは手間なので、その点だけ解消できないかは今調査中です。

Discussion