Git-hooks - a practical example with tf docs
Posted in development on September 27, 2023 by Adrian Wyssmann ‐ 3 min read
You are working on terraform code and want to ensure your documentation is updated after you made some changes. Why don’t you use git-hooks for that?
A long time ago I wrote about git-hooks, today I want to give you a practicle example on how I ensure my terraform documetation stays up-to-date.
terraform-docs
Not sure if you every heard of terraform-docs, but it’s a tool which generates terraform modules documentation in various formats. You can define a config file .terraform-docs.yml
which defines how your documentations shall look like. My $HOME\.terraform-docs.yml
looks as follows:
formatter: "markdown" # this is required
sections:
hide: []
show: []
content: |-
{{ .Inputs }}
{{ .Outputs }}
{{ .Resources }}
output:
file: "README.md"
mode: inject
template: |-
<!-- BEGIN_TF_DOCS -->
{{ .Content }}
<!-- END_TF_DOCS -->
sort:
enabled: false
by: name
settings:
anchor: true
color: true
default: true
description: false
escape: true
hide-empty: false
html: true
indent: 2
lockfile: true
read-comments: true
required: true
sensitive: false
type: true
A practical example
If you are using terraform-docs you may actually want to ensure, that the docs are created before you commit changes to git. This can be achieved by githooks
I define a path where my script like
git config core.hooksPath ~/.config/git/hooks
Create the folder
mkdir -p ~/.config/git/hooks
In that folder I create a file - in this case for the pre-commit-hook- named
pre-commit
I make it executable and add the following code
#!/usr/bin/env bash set -eo pipefail set -o errexit set -o errtrace shopt -s inherit_errexit if [[ -f "./.git/hooks/pre-commit" ]]; then sh ./.git/hooks/pre-commit fi # @description: generates the tf-doc incl. submodules if applicable function tfdocu_do() { # terraform-docs will locate any available configuration file without needing to explicitly pass the --config flag. if [ -z "$TF_DOCS_CONF" ]; then if [ -f "./.terraform-docs.yml" ]; then TF_DOCS_CONF="./.terraform-docs.yml" else TF_DOCS_CONF="$HOME/.tfdocs.d/.terraform-docs.yml" fi fi if terraform-docs -c $TF_DOCS_CONF $1; then git add "$1/README.md" fi } # @description: iterates over all modules and triggers creation of tf docu function tfdocu() { for dir in $(find . -maxdepth 1 -type d -not -path '*/.*' -not -path '.'); do echo "[Info] Running terraform-docs for '$dir'" tfdocu_do $dir done if [[ -n "$(ls -A *.tf 2>/dev/null)" ]]; then dir="." echo "[Info] Running terraform-docs for '$dir'" tfdocu_do $dir fi } ## we want terraform stuff only to be run for projects using terraform if [[ -n "$(ls -A *.tf 2>/dev/null)" || -n "$(find . -maxdepth 2 -not -path '*/.*' -not -path '.' -type f -name '*.tf')" ]]; then tfdocu # "skeletons" will not be checked if [[ "$(pwd)" == *"skeleton"* ]]; then echo "[Info] This looks like a 'skeleton', so please manually run `terraform fmt`" else terraform fmt -recursive fi fi
So now when you do a git commit in a terraform related repo, it will create the docu automatically:
$ git commit -m"docu: use new template"
./module1
module1\README.md updated successfully
./module2
module2\README.md updated successfully
...
[feature/test-pre-commit-hook 5485ebd] docu: use new template
1 files changed, 1 insertions(+), 1 deletions(-)
What’s next?
Rather than copying code around, setup a repo for your team where you store all shared git hooks. Mine can be found at here.
git clone [email protected]/papanito/git-hooks ~/.config/git/hooks