Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
A Terraform validation and formatting pre-commit hook
#!/usr/bin/env bash
set -e
# Formats any *.tf files according to the hashicorp convention
files=$(git diff --cached --name-only)
for f in $files
do
if [ -e "$f" ] && [[ $f == *.tf ]]; then
#terraform validate `dirname $f`
terraform fmt $f
git add $f
fi
done
@eschwartz

This comment has been minimized.

Copy link

@eschwartz eschwartz commented Feb 22, 2018

This is great, thanks!

The one issue I see is that it will fully stage any files output by git diff
If you have any partially staged files,
this hook will fully stage them.

I might suggest something like this:

#!/usr/bin/env bash
set -e

# Formats any *.tf files according to the hashicorp convention
files=$(git diff --cached --name-only)
for f in $files
do
  if [ -e "$f" ] && [[ $f == *.tf ]]; then
    /usr/local/bin/terraform fmt -check=true $f
  fi
done

which will exit 1 if any files are not properly formatted.
Not as automagical, but it will also prevent any unintended consequences

@atrepca

This comment has been minimized.

Copy link

@atrepca atrepca commented Apr 6, 2018

Add --diff-filter=d to the git diff command to filter deleted files, can't run fmt on those.

@pangteypiyush

This comment has been minimized.

Copy link

@pangteypiyush pangteypiyush commented Sep 11, 2019

Format tfvars files [[ "${f##*.}" =~ ^(tf|tfvars)$ ]]

@211217613

This comment has been minimized.

Copy link

@211217613 211217613 commented Jan 3, 2020

Format tfvars files [[ "${f##*.}" =~ ^(tf|tfvars)$ ]]

can you explain this regex?

@v-zhuravlev

This comment has been minimized.

Copy link

@v-zhuravlev v-zhuravlev commented Nov 9, 2020

I like to avoid magic git add as well.
Here is @eschwartz suggested version with extra error message

#!/usr/bin/env bash
set -e

# Formats any *.tf files according to the hashicorp convention
files=$(git diff --cached --name-only)
for f in $files
do
  if [ -e "$f" ] && [[ "${f##*.}" =~ ^(tf|tfvars)$ ]]; then
    terraform fmt -check=true $f || (echo "pre-hook: Please apply 'terraform fmt' for file $f before commiting or remove this file from stage" && false )
fi
done
@slmg

This comment has been minimized.

Copy link

@slmg slmg commented Dec 11, 2020

Extending the previous ideas: avoid automatically running git add, however automatically run terraform fmt and let the user the responsibility to stage changes or not.

#!/usr/bin/env bash
set -e

# Formats any *.tf files according to the hashicorp convention
files=$(git diff --cached --name-only)
for f in $files
do
  if [ -e "$f" ] && [[ $f == *.tf ]]; then
    terraform fmt -check=true $f > /dev/null || {
        echo "pre-hook: Incorrect formatting, let me fix this for you"
        cmd="terraform fmt -recursive"
        echo "Running '$cmd'..."
        $cmd
        echo "Done. You may now stage changes."
    }
  fi
done
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment