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

feat: Adds support for Terrascan #195

Merged
merged 3 commits into from
Apr 22, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .pre-commit-hooks.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -82,3 +82,9 @@
files: \.tf$
exclude: \.+.terraform\/.*$
require_serial: true

- id: terrascan
name: terrascan
description: Runs terrascan on Terraform templates.
language: script
entry: terrascan.sh
9 changes: 6 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,14 @@
* [`TFSec`](https://github.com/liamg/tfsec) required for `terraform_tfsec` hook.
* [`coreutils`](https://formulae.brew.sh/formula/coreutils) required for `terraform_validate` hook on macOS (due to use of `realpath`).
* [`checkov`](https://github.com/bridgecrewio/checkov) required for `checkov` hook.
* [`terrascan`](https://github.com/accurics/terrascan) required for `terrascan` hook.

or build and use the Docker image locally as mentioned below in the `Run` section.

##### MacOS

```bash
brew install pre-commit gawk terraform-docs tflint tfsec coreutils checkov
brew install pre-commit gawk terraform-docs tflint tfsec coreutils checkov terrascan
```

##### Ubuntu 18.04
Expand All @@ -32,6 +33,7 @@ pip3 install pre-commit
curl -L "$(curl -s https://api.github.com/repos/terraform-docs/terraform-docs/releases/latest | grep -o -E "https://.+?-linux-amd64.tar.gz")" > terraform-docs.tgz && tar xzf terraform-docs.tgz && chmod +x terraform-docs && sudo mv terraform-docs /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/
curl -L "$(curl -s https://api.github.com/repos/tfsec/tfsec/releases/latest | grep -o -E "https://.+?tfsec-linux-amd64")" > tfsec && chmod +x tfsec && mv tfsec /usr/bin/
curl -L "$(curl -s https://api.github.com/repos/accurics/terrascan/releases/latest | grep -o -E "https://.+?_Linux_x86_64.tar.gz")" > terrascan.tar.gz && tar -xf terrascan.tar.gz terrascan && rm terrascan.tar.gz && sudo mv terrascan /usr/bin/
python3.7 -m pip install -U checkov
```

Expand Down Expand Up @@ -72,9 +74,9 @@ or you can also build and use the provided Docker container, which wraps all dep
```bash
# first building it
docker build -t pre-commit .
# and then running it in the folder
# and then running it in the folder
# with the terraform code you want to check by executing
docker run -v $(pwd):/lint -w /lint pre-commit run -a
docker run -v $(pwd):/lint -w /lint pre-commit run -a
```

## Available Hooks
Expand All @@ -93,6 +95,7 @@ There are several [pre-commit](https://pre-commit.com/) hooks to keep Terraform
| `terragrunt_validate` | Validates all [Terragrunt](https://github.com/gruntwork-io/terragrunt) configuration files (`*.hcl`) |
| `terraform_tfsec` | [TFSec](https://github.com/liamg/tfsec) static analysis of terraform templates to spot potential security issues. |
| `checkov` | [checkov](https://github.com/bridgecrewio/checkov) static analysis of terraform templates to spot potential security issues. |
| `terrascan` | [terrascan](https://github.com/accurics/terrascan) Detect compliance and security violations. |

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 Down
73 changes: 73 additions & 0 deletions terrascan.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
#!/usr/bin/env bash
set -eo pipefail

main() {
initialize_
parse_cmdline_ "$@"

# propagate $FILES to custom function
terrascan_ "$ARGS" "$FILES"
}

terrascan_() {
# consume modified files passed from pre-commit so that
# terrascan runs against only those relevant directories
for file_with_path in $FILES; do
file_with_path="${file_with_path// /__REPLACED__SPACE__}"
paths[index]=$(dirname "$file_with_path")

let "index+=1"
done

for path_uniq in $(echo "${paths[*]}" | tr ' ' '\n' | sort -u); do
path_uniq="${path_uniq//__REPLACED__SPACE__/ }"
pushd "$path_uniq" > /dev/null
terrascan scan -i terraform $ARGS
popd > /dev/null
done
}

initialize_() {
# get directory containing this script
local dir
local source
source="${BASH_SOURCE[0]}"
while [[ -L $source ]]; do # resolve $source until the file is no longer a symlink
dir="$(cd -P "$(dirname "$source")" > /dev/null && pwd)"
source="$(readlink "$source")"
# if $source was a relative symlink, we need to resolve it relative to the path where the symlink file was located
[[ $source != /* ]] && source="$dir/$source"
done
_SCRIPT_DIR="$(dirname "$source")"

# source getopt function
# shellcheck source=lib_getopt
. "$_SCRIPT_DIR/lib_getopt"
}

parse_cmdline_() {
declare argv
argv=$(getopt -o a: --long args: -- "$@") || return
eval "set -- $argv"

for argv; do
case $argv in
-a | --args)
shift
ARGS+=("$1")
shift
;;
--)
shift
FILES+=("$@")
break
;;
esac
done
}

# global arrays
declare -a ARGS=()
declare -a FILES=()

[[ ${BASH_SOURCE[0]} != "$0" ]] || main "$@"