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 8 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;
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/
70 changes: 70 additions & 0 deletions management/instance_types/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
# Scalr Policy Library

## Policy :: instance_types

Enforces a whitelist of allowed instance types/sizes for AWS, Azure and Google.

### Files

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

### How to use this policy

#### Cloning and testing

---

NOTE: See [Terraform CLI with Scalr](https://docs.scalr.com/en/latest/cli.html) for details on creating an API token to enable the CLI to work with Scalr

---

The Terraform config in this repo is an example that requires AWS, Azure and Google credentials.

1. Clone this repository
2. Edit instances_types.rego as required, e.g. to adjust whitelists
3. Replace instances_types.tf with your own Terraform configuration that you need to test the policy against. Ensure the config contains a [partial backend configuration](https://www.terraform.io/docs/language/settings/backends/configuration.html#partial-configuration) similar to this with a workspace name of your choice.

```javascript
terraform {

backend "remote" {
workspaces {
name = "{ws-name}"
}
}
}
```

4. Set your remote backed hostname and organization (Scalr environment) parameters using `TF_CLI_ARGS_init` as follows.

`export TF_CLI_ARGS_init='-backend-config="hostname={your-scalr-hostname}" -backend-config="organization={your-scalr-evironment_id}"'`.

When using Scalr SaaS the hostname will be in the form `my-account.scalr.io`.
The environment_id will be in the form `env-{random_string}` and can be obtained from the environment dashboard.

5. Run `terraform init` to initialize the workspace.
6. Run `./generate_plan.sh` to generate a plan and download the mock data.
7. Evaluate the policy using `opa eval -f pretty --data instance_types.rego -i input.json data.terraform.deny`

#### Adding to a Policy Group

You can now create a policy group for this policy or add it to an existing policy group. See [Policy Groups](https://docs.scalr.com/en/latest/opa.html#creating-policy-groups) for a detailed explanation. In summary do the following.

1. Copy the policy file (`instance_types.rego`) to the VCS repo for the policy group.
2. Add and entry to `scalr-policy.hcl` file to enable the policy and set the enforcement level. e.g.

```javascript
version = "v1"

policy "instance_types" {
enabled = true
enforcement_level = "hard-mandatory"
}
```

3. If you are creating a new policy group you can now set that up in the Scalr UI. If it is an existing policy group it will automatically re-sync when you commit the new policy file and updated `scalr-policy.hcl` to the repo.
11 changes: 11 additions & 0 deletions management/instance_types/eval.output
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
[
"aws_ec2_capacity_reservation.invalid_type :: 'instance_type' of 't3.nano' is not allowed",
"aws_instance.invalid_type :: 'instance_type' of 't2.medium' is not allowed",
"aws_launch_configuration.invalid_type :: 'instance_type' of 't3.large' is not allowed",
"azurerm_linux_virtual_machine.invalid-alvm :: 'size' of 'Standard_A2' is not allowed",
"azurerm_linux_virtual_machine_scale_set.invalid-alvmss :: 'sku' of 'Standard_F2' is not allowed",
"azurerm_windows_virtual_machine.invalid-awvm :: 'size' of 'Standard_F2' is not allowed",
"azurerm_windows_virtual_machine_scale_set.invalid-awvmss :: 'sku' of 'Standard_F2' is not allowed",
"google_compute_instance.invalid_type :: 'machine_type' of 'e2-medium' is not allowed",
"google_compute_instance_template.invalid_type :: 'machine_type' of 'e2-medium' is not allowed"
]
37 changes: 37 additions & 0 deletions management/instance_types/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
Loading