🐷

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 のファイルにのみフックが適用されます。

この設定により、コミット時に 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