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: Add scanning of Terraform Files and Plans #5

Merged
merged 12 commits into from
Apr 4, 2024
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
62 changes: 59 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,20 +49,76 @@ steps:
path: "infrastructure/cdk.out"
```

### Terraform Files Scanning

Add the following to your `pipeline.yml`, the plugin will scan a specific Terraform File and related Parameter file.

```yaml
steps:
- label: "Scan Terraform File"
env:
- WIZ_API_ID: "<your-id-goes-here>"
plugins:
- wiz#v1.1.0:
scan-type: 'terraform-files'
file-path: 'main.tf'
parameter-files: 'variables.tf'
```

By default, `file-path` will be the root of your repository, and scan all Terraform files in the directory.
To change the directory, add the following to your `pipeline.yml`, the plugin will scan the chosen directory.

```yaml
steps:
- label: "Scan Terraform Files in Directory"
env:
- WIZ_API_ID: "<your-id-goes-here>"
plugins:
- wiz#v1.1.0:
scan-type: 'terraform-files'
file-path: 'my-terraform-files'
```

### Terraform Plan Scanning

Add the following to your `pipeline.yml`, the plugin will scan a Terraform Plan.

```yaml
steps:
- label: "Scan Terraform Plan"
command: terraform plan -out plan.tfplan && terraform show -json plan.tfplan | jq -er . > plan.tfplanjson
env:
- WIZ_API_ID: "<your-id-goes-here>"
plugins:
- wiz#v1.1.0:
scan-type: 'terraform-plan'
file-path: 'plan.tfplanjson'
```

## Configuration

### `api-secret-env` (Optional, string)

The environment variable that the Wiz API Secret is stored in. Defaults to using `WIZ_API_SECRET`. Refer to the [documentation](https://buildkite.com/docs/pipelines/secrets#using-a-secrets-storage-service) for more information about managing secrets on your Buildkite agents.

### `scan-type` (Required, string) : 'docker | iac'
### `file-path` (Optional, string)

The file or directory to scan, defaults to the root directory of repository.
Used when `scan-type` is `terraform-files` and `terraform-plan`.

The scan type can be either docker or iac
### `scan-type` (Required, string) : 'docker | iac | terraform-files | terraform-plan'

The type of resource to be scanned.

### `image-address` (Optional, string)

The path to image file, if the `scan-type` is `docker`

### `parameter-files` (Optional, string)

Comma separated list of globs of external parameter files to include while scanning e.g., `variables.tf`
Used when `scan-type` is `terraform-files`.

### `path` (Optional, string)

The path to `cdk.out` folder containing CloudFormation stack(s), if the `scan-type` is `iac`
Expand All @@ -81,4 +137,4 @@ docker-compose run --rm tests
2. Make the changes
3. Run the tests
4. Commit and push your changes
5. Send a pull request
5. Send a pull request
78 changes: 73 additions & 5 deletions hooks/post-command
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@ set -uo pipefail
WIZ_DIR="$HOME/.wiz"
SCAN_TYPE="${BUILDKITE_PLUGIN_WIZ_SCAN_TYPE:-}"
CDK_PATH="${BUILDKITE_PLUGIN_WIZ_PATH:-}"
FILE_PATH="${BUILDKITE_PLUGIN_WIZ_FILE_PATH:-}"
PARAMETER_FILES="${BUILDKITE_PLUGIN_WIZ_PARAMETER_FILES:-}"

if [[ -z "${SCAN_TYPE}" ]]; then
echo "Missing scan type. Possible values: 'iac', 'docker'"
echo "Missing scan type. Possible values: 'iac', 'docker', 'terraform-files', 'terraform-plan'"
exit 1
fi

Expand All @@ -21,11 +23,16 @@ if [ "${SCAN_TYPE}" = "iac" ] && [[ -z "${BUILDKITE_PLUGIN_WIZ_PATH:-}" ]]; then
exit 1
fi

if [ "${SCAN_TYPE}" = "terraform-plan" ] && [[ -z "${FILE_PATH}" ]]; then
echo "+++ 🚨 file-path must be specified to Terraform Plan file when scan-type is 'terraform-plan'"
exit 1
fi

api_secret_var="${BUILDKITE_PLUGIN_WIZ_API_SECRET_ENV:-WIZ_API_SECRET}"

if [[ -z "${!api_secret_var:-}" ]] ; then
echo "+++ 🚨 No Wiz API Secret password found in \$${api_secret_var}"
exit 1
if [[ -z "${!api_secret_var:-}" ]]; then
echo "+++ 🚨 No Wiz API Secret password found in \$${api_secret_var}"
exit 1
fi

#TODO move this to agent-startup so all agents have wiz setup to save time, possibly directly as cli
Expand Down Expand Up @@ -119,7 +126,60 @@ iacScan() {
esac
# buildkite-agent artifact upload "result/**/*" --log-level info
# this post step will be used in template to check the step was run
echo "${BUILDKITE_BUILD_ID}" > check-file && buildkite-agent artifact upload check-file
echo "${BUILDKITE_BUILD_ID}" >check-file && buildkite-agent artifact upload check-file
}

terraformFilesScan() {
mkdir -p result
docker run \
--rm -it \
--mount type=bind,src="$WIZ_DIR",dst=/cli,readonly \
--mount type=bind,src="$PWD",dst=/scan \
wiziocli.azurecr.io/wizcli:latest-amd64 \
iac scan \
--name "$BUILDKITE_JOB_ID" -f human -o /scan/result/output,human \
--types 'Terraform' \
--path "/scan/$FILE_PATH" \
--parameter-files "${PARAMETER_FILES}"

exit_code="$?"
case $exit_code in
0)
buildAnnotation "Terraform Files" "$BUILDKITE_LABEL" true "result/output" | buildkite-agent annotate --append --context 'ctx-wiz-terraform-files-success' --style 'success'
;;
*)
buildAnnotation "Terraform Files" "$BUILDKITE_LABEL" false "result/output" | buildkite-agent annotate --append --context 'ctx-wiz-terraform-files-warning' --style 'warning'
;;
esac
# buildkite-agent artifact upload "result/**/*" --log-level info
# this post step will be used in template to check the step was run
echo "${BUILDKITE_BUILD_ID}" >check-file && buildkite-agent artifact upload check-file
}

terraformPlanScan() {
mkdir -p result
docker run \
--rm -it \
--mount type=bind,src="$WIZ_DIR",dst=/cli,readonly \
--mount type=bind,src="$PWD",dst=/scan \
wiziocli.azurecr.io/wizcli:latest-amd64 \
iac scan \
--name "$BUILDKITE_JOB_ID" -f human -o /scan/result/output,human \
--types 'Terraform' \
--path "/scan/$FILE_PATH"

exit_code="$?"
case $exit_code in
0)
buildAnnotation "Terraform Plan" "$BUILDKITE_LABEL" true "result/output" | buildkite-agent annotate --append --context 'ctx-wiz-terraform-plan-success' --style 'success'
;;
*)
buildAnnotation "Terraform Plan" "$BUILDKITE_LABEL" false "result/output" | buildkite-agent annotate --append --context 'ctx-wiz-terraform-plan-warning' --style 'warning'
;;
esac
# buildkite-agent artifact upload "result/**/*" --log-level info
# this post step will be used in template to check the step was run
echo "${BUILDKITE_BUILD_ID}" >check-file && buildkite-agent artifact upload check-file
}

case "${SCAN_TYPE}" in
Expand All @@ -131,4 +191,12 @@ docker)
setupWiz
dockerImageScan
;;
terraform-files)
setupWiz
terraformFilesScan
;;
terraform-plan)
setupWiz
terraformPlanScan
;;
esac
6 changes: 6 additions & 0 deletions plugin.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,21 @@ configuration:
properties:
api-secret-env:
type: string
file-path:
type: string
image-address:
type: string
parameter-files:
type: string
path:
type: string
scan-type:
type: string
enum:
- docker
- iac
- terraform-files
- terraform-plan
required:
- scan-type
additionalProperties: false
15 changes: 12 additions & 3 deletions tests/post-command.bats
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ load "$BATS_PLUGIN_PATH/load.bash"
# Uncomment the following line to debug stub failures
# export BUILDKITE_AGENT_STUB_DEBUG=/dev/tty

setup () {
setup() {
export BUILDKITE_PLUGIN_WIZ_SCAN_TYPE="docker"
export BUILDKITE_PLUGIN_WIZ_IMAGE_ADDRESS="ubuntu:22.04"
export WIZ_DIR="$HOME/.wiz"
Expand Down Expand Up @@ -71,6 +71,15 @@ setup () {
export BUILDKITE_PLUGIN_WIZ_SCAN_TYPE=""

run "$PWD/hooks/post-command"
assert_output "Missing scan type. Possible values: 'iac', 'docker'"
assert_failure
assert_output "Missing scan type. Possible values: 'iac', 'docker', 'terraform-files', 'terraform-plan'"
assert_failure
}

@test "Terraform Plan scan without File specified" {
export BUILDKITE_PLUGIN_WIZ_SCAN_TYPE="terraform-plan"
export BUILDKITE_PLUGIN_WIZ_FILE_PATH=""

run "$PWD/hooks/post-command"
assert_output --partial "file-path must be specified to Terraform Plan file when scan-type is 'terraform-plan'"
assert_failure
}