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

Eval example #32

Open
wants to merge 10 commits into
base: master
Choose a base branch
from
Open
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
31 changes: 31 additions & 0 deletions .github/workflows/opa.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,34 @@ jobs:
placement
providers
user

test-new-style:
runs-on: ubuntu-latest
container:
image: ubuntu:latest # Because it has 'curl'
options: --cpus 1
steps:
- name: Checkout
uses: actions/[email protected]
- name: Install OPA
env:
OPA_VERSION: "0.27.1"
run: |-
apt-get -yq update && apt-get install -yq curl;
curl -L -o /usr/bin/opa https://github.com/open-policy-agent/opa/releases/download/v${OPA_VERSION}/opa_linux_amd64 2>/dev/null;
chmod +x /usr/bin/opa;
- name: Test
env:
TERM: xterm-256color
run: |-
# Directories having 'main.tf' are considered a 'new-style' example
dirs=$(find . -name 'main.tf' | awk -F'/[^/]*$' '{print $1}' | sort | uniq);
for polgrp in $dirs; do
# Call opa test command for every Rego file in every example directory.
for pol in $(find $polgrp -name '*.rego'); do
tput setaf 2;
echo "Test $pol";
tput sgr0;
opa eval -f pretty --data $pol -i ${pol%.rego}.input.json data.terraform.deny;
done;
done;
75 changes: 45 additions & 30 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ A sample collection of OPA policies to test against Terraform run in Scalr.

## Policy Files

**NOTE:** The policy files and test data are being refactored to use `opa eval` rather than `opa test` to provide examples and proof of testing. `opa eval` is what is actually used to run the policies in Scalr and more likely to be used in development workflows when creating and testing policies. This refactoring is work in progress so you will find a mixture of policy files in this repository as follows.

### `opa test` policy files

Each sample policy comprises 3 files.

- `*.rego`: The OPA policy
Expand All @@ -22,6 +26,17 @@ Each sample policy comprises 3 files.

Each folder also includes an example `scalr-policy.hcl` file. These files are used by Scalr to implement enforcement levels for each policy (`hard-mandatory`, `soft-mandatory`, `advisory`). See [Enabling and Enforcing Policy](https://docs.scalr.com/en/latest/opa.html#enabling-and-enforcing-policy) for more details.

### `opa eval` policy files

Each policy is in it's own subdirectory along with an example terraform config that was used to test the policy. The files are as follows.

| Files | Description |
|---|---|
| {policy}.rego | The OPA policy |
| {policy}.tf | Terraform config used to generate mock data for policy evaluation |
| {policy}.input.json | Mock data (tfplan, tfrun) generated by Scalr |
| eval.output | Expected output from running `POL={policy} opa eval -f pretty --data ${POL}.rego -i ${POL}.input.json data.terraform.deny` |

## Policy Evaluation

You can evaluate a policy against your own terraform plans using the Terraform CLI and `opa eval` as follows.
Expand All @@ -37,36 +52,36 @@ $ opa eval --format pretty --data policy.rego -i plan.json data.terraform.deny
Summary descriptions of each policy. Detailed descriptions of each rule can be found as comments in the policy file.
Many policies contain arrays of values that are checked against resources. The arrays and reason messages are of course customisable.

| Policy | Description |
| -------------------------------------- | ------------------------------------------------------------------------ |
| [aws/enforce_aws_iam_and_workspace.rego](https://github.com/Scalr/sample-tf-opa-policies/blob/master/aws/enforce_aws_iam_and_workspace.rego) | Checks valid IAM roles for provider and workspace. |
| [aws/enforce_aws_resource.rego](https://github.com/Scalr/sample-tf-opa-policies/blob/master/aws/enforce_aws_resource.rego) | Check resource types against an allowed list. |
| [aws/enforce_cidr.rego](https://github.com/Scalr/sample-tf-opa-policies/blob/master/aws/enforce_cidr.rego) | Check security group CIDR blocks contain allowed CIDR's. |
| [aws/enforce_ebs_del_on_term.rego](https://github.com/Scalr/sample-tf-opa-policies/blob/master/aws/enforce_ebs_del_on_term.rego) | Check `delete_on_termination = true` is set for EBS volumes. |
| [aws/enforce_iam_instance_profiles.rego](https://github.com/Scalr/sample-tf-opa-policies/blob/master/aws/enforce_iam_instance_profiles.rego) | Check IAM instance profile is in allowed list. |
| [aws/enforce_instance_subnets.rego](https://github.com/Scalr/sample-tf-opa-policies/blob/master/aws/enforce_instance_subnets.rego) | Check instances are using allowed subnets |
| [aws/enforce_kms_key_names.rego](https://github.com/Scalr/sample-tf-opa-policies/blob/master/aws/enforce_kms_key_names.rego) | Check KMS keys (by name) against allowed list. |
| [aws/enforce_lb_subnets.rego](https://github.com/Scalr/sample-tf-opa-policies/blob/master/aws/enforce_lb_subnets.rego) | Check Loadbalancers are using allowed subnets |
| [aws/enforce_s3_buckets_encryption.rego](https://github.com/Scalr/sample-tf-opa-policies/blob/master/aws/enforce_s3_buckets_encryption.rego) | Check encryption is set for S3 buckets. |
| [aws/enforce_s3_private.rego](https://github.com/Scalr/sample-tf-opa-policies/blob/master/aws/enforce_s3_private.rego) | Check S3 buckets are not public. |
| [aws/enforce_sec_group.rego](https://github.com/Scalr/sample-tf-opa-policies/blob/master/aws/enforce_sec_group.rego) | Check security groups have been specified and are in allowed list. |
| [aws/enforce_rds_subnets.rego](https://github.com/Scalr/sample-tf-opa-policies/blob/master/aws/enforce_rds_subnets.rego) | Check RDS clusters are using allowed subnets |
| [cost/limit_monthly_cost.rego](https://github.com/Scalr/sample-tf-opa-policies/blob/master/cost/limit_monthly_cost.rego) | Check estimated cost against an upper limit. |
| [external_data/random_decision.rego](https://github.com/Scalr/sample-tf-opa-policies/blob/master/external_data/random_decision.rego) | Example of using external data (HTTP GET) in a policy. |
| [gcp/enforce_gcs_private.rego](https://github.com/Scalr/sample-tf-opa-policies/blob/master/gcp/enforce_gcs_private.rego) | Check GCS buckets are not public. |
| [management/denied_provisioners.rego](https://github.com/Scalr/sample-tf-opa-policies/blob/master/management/denied_provisioners.rego) | Checks provisioner types against an allowed list. |
| [management/enforce_ami_owners.rego](https://github.com/Scalr/sample-tf-opa-policies/blob/master/management/enforce_ami_owners.rego) | Checks AMI's being used belong to allowed list of AMI owners. |
| [management/enforce_var_desc.rego](https://github.com/Scalr/sample-tf-opa-policies/blob/master/management/enforce_var_desc.rego) | Checks variables have descriptions. |
| [management/instance_types.rego](https://github.com/Scalr/sample-tf-opa-policies/blob/master/management/instance_types.rego) | Checks instance types/sizes against allowed list. AWS, Azure and GCP. |
| [management/resource_tags.rego](https://github.com/Scalr/sample-tf-opa-policies/blob/master/management/resource_tags.rego) | Checks required tags are configured for all clouds. |
| [management/whitelist_ami.rego](https://github.com/Scalr/sample-tf-opa-policies/blob/master/management/whitelist_ami.rego) | Checks AMI against allowed list or configured from data source. |
| [management/workspace_name.rego](https://github.com/Scalr/sample-tf-opa-policies/blob/master/management/workspace_name.rego) | Simple example of using `tfrun` data and validating a workspace name. |
| [management/workspace_tags.rego](https://github.com/Scalr/sample-tf-opa-policies/blob/master/management/workspace_tags.rego) | Checks workspace is tagged with provider name. |
| [modules/pin_module_version.rego](https://github.com/Scalr/sample-tf-opa-policies/blob/master/modules/pin_module_version.rego) | Enforces use of specific module versions. |
| [modules/required_modules.rego](https://github.com/Scalr/sample-tf-opa-policies/blob/master/modules/required_modules.rego) | Checks resources are only be created via specific modules. |
| [placement/cloud_location.rego](https://github.com/Scalr/sample-tf-opa-policies/blob/master/placement/cloud_location.rego) | Checks resources are deployed to specific regions in each cloud. |
| [providers/blacklist_provider.rego](https://github.com/Scalr/sample-tf-opa-policies/blob/master/providers/blacklist_provider.rego) | Implements a provider blacklist. |
| [user/user.rego](https://github.com/Scalr/sample-tf-opa-policies/blob/master/user/user.rego) | Restricts which users can trigger terraform runs. Works for CLI and VCS. |
| Policy | Type | Description |
| -------------------------------------- | ---- | ------------------------------------------------------------------------ |
| [aws/enforce_aws_iam_and_workspace.rego](https://github.com/Scalr/sample-tf-opa-policies/blob/master/aws/enforce_aws_iam_and_workspace.rego) | test | Checks valid IAM roles for provider and workspace. |
| [aws/enforce_aws_resource.rego](https://github.com/Scalr/sample-tf-opa-policies/blob/master/aws/enforce_aws_resource.rego) | test | Check resource types against an allowed list. |
| [aws/enforce_cidr.rego](https://github.com/Scalr/sample-tf-opa-policies/blob/master/aws/enforce_cidr.rego) | test | Check security group CIDR blocks contain allowed CIDR's. |
| [aws/enforce_ebs_del_on_term.rego](https://github.com/Scalr/sample-tf-opa-policies/blob/master/aws/enforce_ebs_del_on_term.rego) | test | Check `delete_on_termination = true` is set for EBS volumes. |
| [aws/enforce_iam_instance_profiles.rego](https://github.com/Scalr/sample-tf-opa-policies/blob/master/aws/enforce_iam_instance_profiles.rego) | test | Check IAM instance profile is in allowed list. |
| [aws/enforce_instance_subnets.rego](https://github.com/Scalr/sample-tf-opa-policies/blob/master/aws/enforce_instance_subnets.rego) | test | Check instances are using allowed subnets |
| [aws/enforce_kms_key_names.rego](https://github.com/Scalr/sample-tf-opa-policies/blob/master/aws/enforce_kms_key_names.rego) | test | Check KMS keys (by name) against allowed list. |
| [aws/enforce_lb_subnets.rego](https://github.com/Scalr/sample-tf-opa-policies/blob/master/aws/enforce_lb_subnets.rego) | test | Check Loadbalancers are using allowed subnets |
| [aws/enforce_s3_buckets_encryption.rego](https://github.com/Scalr/sample-tf-opa-policies/blob/master/aws/enforce_s3_buckets_encryption.rego) | test | Check encryption is set for S3 buckets. |
| [aws/enforce_s3_private.rego](https://github.com/Scalr/sample-tf-opa-policies/blob/master/aws/enforce_s3_private.rego) | test | Check S3 buckets are not public. |
| [aws/enforce_sec_group.rego](https://github.com/Scalr/sample-tf-opa-policies/blob/master/aws/enforce_sec_group.rego) | test | Check security groups have been specified and are in allowed list. |
| [aws/enforce_rds_subnets.rego](https://github.com/Scalr/sample-tf-opa-policies/blob/master/aws/enforce_rds_subnets.rego) | test | Check RDS clusters are using allowed subnets |
| [cost/limit_monthly_cost.rego](https://github.com/Scalr/sample-tf-opa-policies/blob/master/cost/limit_monthly_cost.rego) | test | Check estimated cost against an upper limit. |
| [external_data/random_decision.rego](https://github.com/Scalr/sample-tf-opa-policies/blob/master/external_data/random_decision.rego) | test | Example of using external data (HTTP GET) in a policy. |
| [gcp/enforce_gcs_private.rego](https://github.com/Scalr/sample-tf-opa-policies/blob/master/gcp/enforce_gcs_private.rego) | test | Check GCS buckets are not public. |
| [management/denied_provisioners.rego](https://github.com/Scalr/sample-tf-opa-policies/blob/master/management/denied_provisioners.rego) | test | Checks provisioner types against an allowed list. |
| [management/enforce_ami_owners.rego](https://github.com/Scalr/sample-tf-opa-policies/blob/master/management/enforce_ami_owners.rego) | test | Checks AMI's being used belong to allowed list of AMI owners. |
| [management/enforce_var_desc.rego](https://github.com/Scalr/sample-tf-opa-policies/blob/master/management/enforce_var_desc.rego) | test | Checks variables have descriptions. |
| [management/instance_types](https://github.com/Scalr/sample-tf-opa-policies/blob/master/management/instance_types/instance_types.rego) | **eval** | Checks instance types/sizes against allowed list. AWS, Azure and GCP. |
| [management/resource_tags.rego](https://github.com/Scalr/sample-tf-opa-policies/blob/master/management/resource_tags.rego) | test | Checks required tags are configured for all clouds. |
| [management/whitelist_ami.rego](https://github.com/Scalr/sample-tf-opa-policies/blob/master/management/whitelist_ami.rego) | test | Checks AMI against allowed list or configured from data source. |
| [management/workspace_name.rego](https://github.com/Scalr/sample-tf-opa-policies/blob/master/management/workspace_name.rego) | test | Simple example of using `tfrun` data and validating a workspace name. |
| [management/workspace_tags.rego](https://github.com/Scalr/sample-tf-opa-policies/blob/master/management/workspace_tags.rego) | test | Checks workspace is tagged with provider name. |
| [modules/pin_module_version.rego](https://github.com/Scalr/sample-tf-opa-policies/blob/master/modules/pin_module_version.rego) | test | Enforces use of specific module versions. |
| [modules/required_modules.rego](https://github.com/Scalr/sample-tf-opa-policies/blob/master/modules/required_modules.rego) | test | Checks resources are only be created via specific modules. |
| [placement/cloud_location.rego](https://github.com/Scalr/sample-tf-opa-policies/blob/master/placement/cloud_location.rego) | test | Checks resources are deployed to specific regions in each cloud. |
| [providers/blacklist_provider.rego](https://github.com/Scalr/sample-tf-opa-policies/blob/master/providers/blacklist_provider.rego) | test | Implements a provider blacklist. |
| [user/user.rego](https://github.com/Scalr/sample-tf-opa-policies/blob/master/user/user.rego) | test | Restricts which users can trigger terraform runs. Works for CLI and VCS. |

## Contributions

Expand Down
37 changes: 37 additions & 0 deletions SCRIPTS/generate_mock.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
#!/bin/bash

# Runs Terraform plan and downloads OPA mock data file

# Get TOKEN, and backend details

HOSTNAME=$(jq -r '.backend.config.hostname' .terraform/terraform.tfstate)
if [[ ! "$HOSTNAME" ]]; then
error "No hostname found in .terraform/terraform.tfstate. Ensure terraform init has been run"
fi

TOKEN=$(awk -v URL=$HOSTNAME '{if ($2 ~ URL) {getline;print $3}}' < ~/.terraformrc | sed 's/"//g')
if [[ ! "$TOKEN" ]]; then
error "No token found in ~/.terraformrc for $HOSTNAME"
fi

# Run terraform plan

echo "Running terraform plan"

terraform plan | tee .plan.out

# Extract the run_id

RUN_ID=$(grep "https://${HOSTNAME}/app/-.*/runs/run-" .plan.out | cut -d'/' -f 8 | cut -c1-19)

# Download the mock data zip file and unpack

echo "Downloading mock data"

curl -o .mock.zip -X GET 'https://'${HOSTNAME}'/api/iacp/v3/runs/'${RUN_ID}'/policy-input?' -H 'Authorization: Bearer '${TOKEN} -H 'Content-Type: application/vnd.api+json' -H 'prefer: profile=preview'

tar xvf .mock.zip

echo "Mock data file downloaded to 'input.json'"

rm -f .plan.out .mock.zip
48 changes: 0 additions & 48 deletions management/instance_types.rego

This file was deleted.

5 changes: 5 additions & 0 deletions management/instance_types/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
.terraform.lock.hcl
.terraform/
.plan.out
.mock.zip
input.json
2 changes: 2 additions & 0 deletions management/instance_types/.terraformignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
.terraform.lock.hcl
.terraform/
Loading