Skip to content

Instantly share code, notes, and snippets.

@jamtur01
Created October 18, 2016 21:54
Show Gist options
  • Save jamtur01/a567078b7ba545c3492f7cd32a65450d to your computer and use it in GitHub Desktop.
Save jamtur01/a567078b7ba545c3492f7cd32a65450d to your computer and use it in GitHub Desktop.
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
Copy link

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
Copy link

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
Copy link

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

@211217613
Copy link

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

can you explain this regex?

@v-zhuravlev
Copy link

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
Copy link

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