4
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

gitのpre-commitでterraform書式チェックを自動化する

Posted at

はじめに

terraformでインフラ運用している中で、credentials情報をローカルに持てない等のセキュリティポリシーが理由でローカル(コーディング環境)からterraform実行できないケースがあると思います。
そんなとき、書式ミスや変数参照ミスなどをterraform実行環境にデプロイしてみないとわからないのは、非効率ですよね。仮にデプロイをパイプライン等で自動化していても、パイプライン実行の待ち時間が無駄ですし、タイポなどのしょうもないミスでcommit履歴が汚れるのは微妙です。。

そこで、gitのpre-commit機能を利用してcommit前にterraform fmt/init/validateを自動実行するようにしてみました。これによりコマンドが成功した場合のみcommitされ、失敗した場合は、commitされずにエラー内容が出力されます。

うまく動かない等があれば、コメントいただければと思います。

実行例

成功例

$ git commit -m "test"
Directory: terraform/ terraform fmt: Passed
Directory: terraform/ terraform init: Passed
Directory: terraform/ terraform validate: Passed
Directory: terraform/environment/iam/ terraform fmt: Passed
Directory: terraform/environment/iam/ terraform init: Passed
Directory: terraform/environment/iam/ terraform validate: Passed
Directory: terraform/environment/lambda/ terraform fmt: Passed
Directory: terraform/environment/lambda/ terraform init: Passed
Directory: terraform/environment/lambda/ terraform validate: Passed
[master 9b47d9e] test
 8 files changed, 77 insertions(+), 14 deletions(-)
 create mode 100644 terraform/environment/iam/dev.tfvars
 create mode 100644 terraform/environment/iam/prd.tfvars
 create mode 100644 terraform/environment/iam/variables.tf
 create mode 100644 terraform/environment/lambda/variables.tf

失敗例

$ git commit -m "test"
Directory: terraform/ terraform fmt: Passed
Directory: terraform/ terraform init: Passed
Directory: terraform/ terraform validate: Passed
Directory: terraform/environment/iam/ terraform fmt: Passed
Directory: terraform/environment/iam/ terraform init: Passed
Directory: terraform/environment/iam/ terraform validate: Passed
Directory: terraform/environment/lambda/ terraform fmt: Passed
Directory: terraform/environment/lambda/ terraform init: Passed

Error: Missing required argument

  on main.tf line 16, in module "get_lambda":
  16: module "get_lambda" {

The argument "memory_size" is required, but no definition was found.


Error: Unsupported argument

  on main.tf line 23, in module "get_lambda":
  23:   memory_sze            = 256

An argument named "memory_sze" is not expected here. Did you mean
"memory_size"?

Directory: terraform/environment/lambda/ terraform validate: Failed

実行環境

  • WSL (Ubuntu 18.04)
  • git version 2.17.1
  • Terraform v0.12.19

準備から実行まで

準備1. terraformインストール

使用しているversionに合わせたterraformをこちらからインストールします。
(すでにインストール済みの場合は不要)

準備2. .gitignore.terraform/を追加

ローカルでterraform initするので、.terraform/配下にpluginやmoduleがインストールされます。
これらはgit管理する必要がないので.gitignoreファイルに以下を追加します。
(すでに記載済みの場合は不要)

.gitignore

.terraform/

準備3. pre-commitファイルを配置

.git/hookspre-commitというファイル名で以下の内容を配置する

.git/hooks/pre-commit
#!/bin/bash -u

work_dir=`pwd`

# 戻り値チェック
check_return_code() {
    cmd_name="$1"
    dir_name="$2"
    rc=$3
    if [ ${rc} -eq 0 ];then
        echo "Directory: ${dir_name} terraform ${cmd_name}: Passed"
    else
        echo "Directory: ${dir_name} terraform ${cmd_name}: Failed"
        exit 1
    fi
}

# terraform実行ディレクトリを抽出する.
# .tfファイルを含むディレクトリ名を変数target_dirに格納. .tfstate及びmoduleは除外.
target_file=$(git diff --cached --name-only --diff-filter=AMRC | grep -E ".tf$|.tfvars$")
if [ -n "${target_file}" ]; then
    target_dir=$(echo ${target_file} | xargs dirname | sort -u)
else
    echo "No change in TF file."
    exit 0
fi

# terraform init/validate
for dir in ${target_dir}
do
    cd ${work_dir}/${dir} || exit 1

    # terraform fmt
    fmt_file=$(terraform fmt)
    check_return_code fmt ${dir} $?

    # fmtにより変更されたファイルをstageする.
    if [ -n "${fmt_file}" ];then
        cd ${work_dir}
        for file in ${fmt_file}
        do
            git add ${dir}/${file}
        done
        cd ${dir}
    fi

    # terraform init
    terraform init -backend=false 1>/dev/null
    check_return_code init ${dir} $?

    # terraform validate
    terraform validate 1>/dev/null
    check_return_code validate ${dir} $?

    #exit 1
done

実行

上記実施後にcommitすると、実行例のようにterraform fmt/init/validateが変更対象のディレクトリごとに実行されます。

注意点

tf version 0.11以前でtfvarsファイルを使用している場合、terraform validateでエラーになります。
その場合、-var-fileオプションでtfvarsを明示的に指定する必要があります。

参考

4
2
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?