We use Terraform to manage our infrastructures based on code as infrastructure approach, the code base is managed in git and multiple developers may change the same code base, one issue we got is someone change the infrastructure code, but forget to push to remote git repository or someone apply the terraform change but did not pull remote change first, this will end up with some unexpected result in the infrastructure. we develop a simple process to solve this issue

terraform-git-hook

the git check script

a simple script to check if developer's local copy is in sync with git remote repos.

#!/bin/bash
# ensure that the terraform directory has no uncommitted changes
if [[ $(git status --porcelain | grep 'terraform/') ]]; then
    echo >&2 "Cannot Terraform with uncommitted changes under terraform/."
    exit 1
fi
# ensure we are up-to-date with the upstream branch
git remote update
local_rev=$(git rev-parse @{0})
remote_rev=$(git rev-parse @{u})
if [[ $local_rev != $remote_rev ]]; then
    base_rev=$(git merge-base @{0} @{u})
    if [[ $local_rev == $base_rev ]]; then
        echo >&2 "Need to pull upstream changes before Terraform."
    elif [[ $remote_rev == $base_rev ]]; then
        echo >&2 "Need to push changes upstream before Terraform."
    else
        echo >&2 "Cannot Terraform: upstream branch has diverged."
    fi
    exit 1
fi

use Makefile to execute all terraform goal

we use Makefile to control every terraform execution, in the make file we could define a goal named "git_check" to call the script above

git_check:
    ./git_check.sh

for each execution goal we could make it depends on goal git_check, this will make sure all the local copy is in sync with remote repos before executing any terraform goal

dns_apply: git_check
    cd network/route53/ && \
    terraform apply plan.bin