gitでコミット(commit)前にterraform fmtやtflintを実行したい時はpre-commit-terraformが便利

2022.07.22

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

「ローカルでもterraform fmtやtflint・tfsecの実行を自動化したい。」

terraformにはコードのフォーマットやテストに便利なcliツールやコマンドが色々あります。 (terraform fmt、terarform validate、tfsec、tflint等)

ただ、このコマンドを毎回手動で実行するのは面倒です。

CI/CDツール上で実行するのもいいですが、CIで失敗する前にローカルで気づけたらより良いですよね。

そんな時に便利なpre-commit-terraformを紹介します。

pre-commit-terraformとは

pre-commitフレームワークで使用できる Terraform の git hook スクリプト集です。

antonbabenko/pre-commit-terraform: pre-commit git hooks to take care of Terraform configurations ??

現在使用できる hook は以下の通りです。 tflint、tfsec、infracost、terraform-docsと充実しています。

terraform-best-practices.comでもpre-commit-terraform紹介されていました。

補足 git hook・pre-commit

git hookやpre-commitが使うのが初めてという方向けに補足です。 (既にご存じの方は、飛ばして問題ありません)

git hookはgitで特定のアクションが実行された際に、スクリプトを実行することができます。 この機能を使用することで、例えばcommit前に特定のコマンドを実行するようなことが可能です。(pre-commit-hook)

pre-commitはGitのpre-commit-hookスクリプトを管理するためのフレームワーク(ツール)です。

pre-commit-hookスクリプトが複雑化した際に、管理や使い回しが大変になることがあると思います。pre-commitを使用することで、スクリプトの管理が楽になります。

git hook はじめの一歩 - Qiita

Python製のツールpre-commitでGitのpre-commit hookを楽々管理!! | DevelopersIO

pre-commit

Git - Git フック

やってみた

ツールのインストール

terraform自体はインストール済みとします。

必要なツールをインストールします。

$ brew install tflint
$ brew install tfsec
$ brew install pre-commit

.pre-commit-config.yamlの準備

プロジェクトのルートディレクトリに.pre-commit-config.yamlを配置します。

.pre-commit-config.yaml

default_stages: [commit]
repos:
    - repo: https://github.com/antonbabenko/pre-commit-terraform
      rev: v1.74.1
      hooks:
          - id: terraform_fmt
          - id: terraform_validate
          - id: terraform_tflint
          - id: terraform_tfsec

ファイルを用意したら、pre-commit-hookスクリプトをインストールします。

$ pre-commit install

手動でチェック実行

以下のコマンドで手動でチェックを実行できます。

$ pre-commit run -a
Terraform fmt............................................................Passed
Terraform validate.......................................................Passed
Terraform validate with tflint...........................................Passed
Terraform validate with tfsec............................................Passed

コミットしてみる

コミットするとチェックが走るようになります。

tfsecで失敗するようにしてからコミットしてみました。 チェックが失敗すると、コミットされません。

$ git add terraform/envs/stg/s3.tf
$ git status
On branch master
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
        modified:   terraform/envs/stg/s3.tf
$
$ git commit -m "test"           
Terraform fmt............................................................Passed
Terraform validate.......................................................Passed
Terraform validate with tflint...........................................Passed
Terraform validate with tfsec............................................Failed
- hook id: terraform_tfsec
- exit code: 1

Result #1 MEDIUM Bucket does not have logging enabled 
────────────────────────────────────────────────────────────────────────────────
  s3.tf:1-3
────────────────────────────────────────────────────────────────────────────────
    1    resource "aws_s3_bucket" "alb_log" {
    2      bucket = "${local.name_prefix}-alb-log-tmp"
    3    }
────────────────────────────────────────────────────────────────────────────────
          ID aws-s3-enable-bucket-logging
      Impact There is no way to determine the access to this bucket
  Resolution Add a logging block to the resource to enable access logging

  More Information
  - https://aquasecurity.github.io/tfsec/v1.26.3/checks/aws/s3/enable-bucket-logging/
  - https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket
────────────────────────────────────────────────────────────────────────────────


  timings
  ──────────────────────────────────────────
  disk i/o             2.063252ms
  parsing              131.668376ms
  adaptation           213.833µs
  checks               7.912041ms
  total                141.857502ms

  counts
  ──────────────────────────────────────────
  modules downloaded   0
  modules processed    2
  blocks processed     382
  files read           12

  results
  ──────────────────────────────────────────
  passed               8
  ignored              1
  critical             0
  high                 0
  medium               1
  low                  0

  8 passed, 1 ignored, 1 potential problem(s) detected.
$ 
$ git status # コミットできていない
On branch master
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
        modified:   terraform/envs/stg/s3.tf

ファイル修正後、checkが通れば通常通りコミットできます。

$ git add terraform/envs/stg/s3.tf
$ git commit -m "fix"
Terraform fmt............................................................Passed
Terraform validate.......................................................Passed
Terraform validate with tflint...........................................Passed
Terraform validate with tfsec............................................Passed

さいごに

pre-commit-terraformの紹介でした。自分でスクリプト書かずに、やりたいことが実現できてよかったです。

今回はfmt,validate,tfsec,tflintの設定だけしましたが、infracostやterraform-docsもあるので必要に応じて使っていきたいです。

以上、AWS事業本部の佐藤(@chari7311)でした。