Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added support for terraform-docs 0.8.0 with proper support for Terraform 0.12 syntax (bye-bye awk) #85

Merged
merged 12 commits into from
Jan 21, 2020
Merged
7 changes: 6 additions & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
repos:
- repo: git://github.com/pre-commit/pre-commit-hooks
rev: v2.2.3
rev: v2.4.0
hooks:
- id: check-yaml
- id: end-of-file-fixer
- id: trailing-whitespace
- id: check-case-conflict
- id: check-merge-conflict
- id: check-executables-have-shebangs
#- repo: git://github.com/jumanjihouse/pre-commit-hooks
# rev: 1.11.2
# hooks:
# - id: shellcheck
# - id: shfmt
1 change: 0 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
## [Unreleased]



<a name="v1.22.0"></a>
## [v1.22.0] - 2020-01-13

Expand Down
21 changes: 9 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,20 +1,19 @@
# Collection of git hooks for Terraform to be used with [pre-commit framework](http://pre-commit.com/)

[![Github tag](https://img.shields.io/github/tag/antonbabenko/pre-commit-terraform.svg)](https://github.com/antonbabenko/pre-commit-terraform/releases) ![](https://img.shields.io/maintenance/yes/2019.svg) [![Help Contribute to Open Source](https://www.codetriage.com/antonbabenko/pre-commit-terraform/badges/users.svg)](https://www.codetriage.com/antonbabenko/pre-commit-terraform)
[![Github tag](https://img.shields.io/github/tag/antonbabenko/pre-commit-terraform.svg)](https://github.com/antonbabenko/pre-commit-terraform/releases) ![](https://img.shields.io/maintenance/yes/2020.svg) [![Help Contribute to Open Source](https://www.codetriage.com/antonbabenko/pre-commit-terraform/badges/users.svg)](https://www.codetriage.com/antonbabenko/pre-commit-terraform)

## How to install

### 1. Install dependencies

* [`pre-commit`](http://pre-commit.com/#install)
* [`terraform-docs`](https://github.com/segmentio/terraform-docs) (required for `terraform_docs` hooks)
* GNU `awk` (required for `terraform_docs` hooks in Terraform 0.12)
* [`TFLint`](https://github.com/wata727/tflint) (required for `terraform_tflint` hook)
* [`pre-commit`](https://pre-commit.com/#install)
* [`terraform-docs`](https://github.com/segmentio/terraform-docs) required for `terraform_docs` hooks. `GNU awk` is required if using `terraform-docs` older than 0.8.0 with Terraform 0.12.
* [`TFLint`](https://github.com/terraform-linters/tflint) required for `terraform_tflint` hook.

##### MacOS

```bash
brew install pre-commit awk terraform-docs tflint
brew install pre-commit gawk terraform-docs tflint
```

##### Ubuntu
Expand All @@ -23,7 +22,7 @@ brew install pre-commit awk terraform-docs tflint
sudo apt install python-pip3 gawk &&\
pip3 install pre-commit
curl -L "$(curl -s https://api.github.com/repos/segmentio/terraform-docs/releases/latest | grep -o -E "https://.+?-linux-amd64")" > terraform-docs && chmod +x terraform-docs && sudo mv terraform-docs /usr/bin/
curl -L "$(curl -s https://api.github.com/repos/wata727/tflint/releases/latest | grep -o -E "https://.+?_linux_amd64.zip")" > tflint.zip && unzip tflint.zip && rm tflint.zip && sudo mv tflint /usr/bin/
curl -L "$(curl -s https://api.github.com/repos/terraform-linters/tflint/releases/latest | grep -o -E "https://.+?_linux_amd64.zip")" > tflint.zip && unzip tflint.zip && rm tflint.zip && sudo mv tflint /usr/bin/
```

### 2. Install the pre-commit hook globally
Expand All @@ -42,7 +41,7 @@ Step into the repository you want to have the pre-commit hooks installed and run
git init
cat <<EOF > .pre-commit-config.yaml
- repo: git://github.com/antonbabenko/pre-commit-terraform
rev: v1.19.0
rev: <VERSION> # Get the latest from: https://github.com/antonbabenko/pre-commit-terraform/releases
hooks:
- id: terraform_fmt
- id: terraform_docs
Expand All @@ -59,7 +58,7 @@ pre-commit run -a

## Available Hooks

There are several [pre-commit](http://pre-commit.com/) hooks to keep Terraform configurations (both `*.tf` and `*.tfvars`) and Terragrunt configurations (`*.hcl`) in a good shape:
There are several [pre-commit](https://pre-commit.com/) hooks to keep Terraform configurations (both `*.tf` and `*.tfvars`) and Terragrunt configurations (`*.hcl`) in a good shape:

| Hook name | Description |
| ------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------- |
Expand All @@ -68,7 +67,7 @@ There are several [pre-commit](http://pre-commit.com/) hooks to keep Terraform c
| `terraform_docs` | Inserts input and output documentation into `README.md`. Recommended. |
| `terraform_docs_without_aggregate_type_defaults` | Inserts input and output documentation into `README.md` without aggregate type defaults. |
| `terraform_docs_replace` | Runs `terraform-docs` and pipes the output directly to README.md |
| `terraform_tflint` | Validates all Terraform configuration files with [TFLint](https://github.com/wata727/tflint). |
| `terraform_tflint` | Validates all Terraform configuration files with [TFLint](https://github.com/terraform-linters/tflint). |
| `terragrunt_fmt` | Rewrites all [Terragrunt](https://github.com/gruntwork-io/terragrunt) configuration files (`*.hcl`) to a canonical format. |

Check the [source file](https://github.com/antonbabenko/pre-commit-terraform/blob/master/.pre-commit-hooks.yaml) to know arguments used for each hook.
Expand All @@ -94,8 +93,6 @@ if they are present in `README.md`.

1. It is possible to pass additional arguments to shell scripts when using `terraform_docs` and `terraform_docs_without_aggregate_type_defaults`. Send pull-request with the new hook if there is something missing.

1. `terraform-docs` works with Terraform 0.12 but support is hackish (it requires `awk` to be installed) and may contain bugs. You can follow the native support of Terraform 0.12 in `terraform-docs` in [issue #62](https://github.com/segmentio/terraform-docs/issues/62).

## Notes about terraform_tflint hooks

1. `terraform_tflint` supports custom arguments so you can enable module inspection, deep check mode etc.
Expand Down
51 changes: 27 additions & 24 deletions terraform_docs.sh
Original file line number Diff line number Diff line change
Expand Up @@ -25,19 +25,38 @@ main() {
esac
done

local hack_terraform_docs=$(terraform version | head -1 | grep -c 0.12)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not enable hack_terraform_docs when terraform-docs is >= v0.8.0. This will allows us to maintain temporary 2 versions of terraform-docs.

@antonbabenko @konstantin-recurly Any thoughts ?

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree. It makes perfect sense to stay compatible for as long as possible.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have updated the logic and added the check for terraform-docs version.
It is checking if terraform-docs version is >= v0.8.0 also added a check if terraform-docs is installed.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here are some testing results:
terraform-docs v0.7.0

terraform-docs version
terraform-docs version v0.0.0- v0.7.0 darwin/amd64 BuildDate: 2019-12-15T00:53:30+0000

❯ pre-commit run -a
Terraform fmt............................................................Passed
Terraform docs...........................................................Passed

terraform-docs v0.8.0

❯ terraform-docs version
terraform-docs version v0.8.0-rc.2 d52122d darwin/amd64 BuildDate: 2020-01-12T20:38:24+0000

❯ pre-commit run -a
Terraform fmt............................................................Passed
Terraform docs...........................................................Failed
hookid: terraform_docs

Files were modified by this hook.

❯ pre-commit run -a
Terraform fmt............................................................Passed
Terraform docs...........................................................Passed

no terraform-docs installed

❯ terraform-docs version
zsh: command not found: terraform-docs

❯ pre-commit run -a
Terraform fmt............................................................Passed
Terraform docs...........................................................Failed
hookid: terraform_docs

terraform-docs is required

local hack_terraform_docs
hack_terraform_docs=$(terraform version | head -1 | grep -c 0.12)

if [[ "$hack_terraform_docs" == "1" ]]; then
which awk 2>&1 >/dev/null || ( echo "awk is required for terraform-docs hack to work with Terraform 0.12"; exit 1)
if [[ ! $(command -v terraform-docs) ]]; then
echo "ERROR: terraform-docs is required by terraform_docs pre-commit hook but is not installed or in the system's PATH."
exit 1
fi

local is_old_terraform_docs
is_old_terraform_docs=$(terraform-docs version | grep -o "v0.[1-7]" | tail -1)

if [[ -z "$is_old_terraform_docs" ]]; then # Using terraform-docs 0.8+ (preferred)

terraform_docs "0" "$args" "$files"

elif [[ "$hack_terraform_docs" == "1" ]]; then # Using awk script because terraform-docs is older than 0.8 and terraform 0.12 is used

if [[ ! $(command -v awk) ]]; then
echo "ERROR: awk is required for terraform-docs hack to work with Terraform 0.12."
exit 1
fi

tmp_file_awk=$(mktemp "${TMPDIR:-/tmp}/terraform-docs-XXXXXXXXXX")
terraform_docs_awk "$tmp_file_awk"
terraform_docs "$tmp_file_awk" "$args" "$files"
rm -f "$tmp_file_awk"
else

else # Using terraform 0.11 and no awk script is needed for that

terraform_docs "0" "$args" "$files"
fi

fi
}

terraform_docs() {
Expand Down Expand Up @@ -76,15 +95,15 @@ terraform_docs() {
fi

if [[ "$terraform_docs_awk_file" == "0" ]]; then
terraform-docs md $args ./ > "$tmp_file"
terraform-docs md "$args" ./ > "$tmp_file"
else
# Can't append extension for mktemp, so renaming instead
tmp_file_docs=$(mktemp "${TMPDIR:-/tmp}/terraform-docs-XXXXXXXXXX")
mv "$tmp_file_docs" "$tmp_file_docs.tf"
tmp_file_docs_tf="$tmp_file_docs.tf"

awk -f "$terraform_docs_awk_file" ./*.tf > "$tmp_file_docs_tf"
terraform-docs md $args "$tmp_file_docs_tf" > "$tmp_file"
terraform-docs md "$args" "$tmp_file_docs_tf" > "$tmp_file"
rm -f "$tmp_file_docs_tf"
fi

Expand All @@ -103,24 +122,19 @@ terraform_docs() {
terraform_docs_awk() {
readonly output_file=$1

cat <<"EOF" > $output_file
cat <<"EOF" > "$output_file"
# This script converts Terraform 0.12 variables/outputs to something suitable for `terraform-docs`
# As of terraform-docs v0.6.0, HCL2 is not supported. This script is a *dirty hack* to get around it.
# https://github.com/segmentio/terraform-docs/
# https://github.com/segmentio/terraform-docs/issues/62

# Script was originally found here: https://github.com/cloudposse/build-harness/blob/master/bin/terraform-docs.awk

{
if ( $0 ~ /\{/ ) {
braceCnt++
}

if ( $0 ~ /\}/ ) {
braceCnt--
}


# ----------------------------------------------------------------------------------------------
# variable|output "..." {
# ----------------------------------------------------------------------------------------------
Expand All @@ -142,8 +156,6 @@ terraform_docs_awk() {
# Print variable|output line
print $0
}


# ----------------------------------------------------------------------------------------------
# default = ...
# ----------------------------------------------------------------------------------------------
Expand Down Expand Up @@ -177,8 +189,6 @@ terraform_docs_awk() {
}
}
}


# ----------------------------------------------------------------------------------------------
# type = ...
# ----------------------------------------------------------------------------------------------
Expand Down Expand Up @@ -211,7 +221,6 @@ terraform_docs_awk() {
} else {
type = $3
}

# legacy quoted types: "string", "list", and "map"
if (type ~ /^[[:space:]]*"(.*?)"[[:space:]]*$/) {
print " type = " type
Expand All @@ -229,8 +238,6 @@ terraform_docs_awk() {
blockTypeCnt -= gsub(/\}/, "")
}
}


# ----------------------------------------------------------------------------------------------
# description = ...
# ----------------------------------------------------------------------------------------------
Expand All @@ -240,8 +247,6 @@ terraform_docs_awk() {
print $0
}
}


# ----------------------------------------------------------------------------------------------
# value = ...
# ----------------------------------------------------------------------------------------------
Expand All @@ -251,8 +256,6 @@ terraform_docs_awk() {
# print $0
# }
#}


# ----------------------------------------------------------------------------------------------
# Newlines, comments, everything else
# ----------------------------------------------------------------------------------------------
Expand Down