Getting Started
Prerequisites
Quick Start
1. Install OPA
1
2
3
4
5
6
# macOS
brew install opa
# Linux
curl -L -o opa https://openpolicyagent.org/downloads/latest/opa_linux_amd64_static
chmod 755 opa && sudo mv opa /usr/local/bin/
2. Run Policy Tests
1
2
3
4
5
# Run all tests with verbose output
opa test ./policies ./tests -v
# Run tests with coverage
opa test ./policies ./tests -v --coverage
1
opa fmt --check --fail policies/ tests/
1
2
3
4
5
6
7
8
# Generate Terraform plan JSON
cd terraform/environments/dev
terraform init
terraform plan -out = tfplan.bin
terraform show -json tfplan.bin > tfplan.json
# Evaluate against policies using Conftest
conftest test tfplan.json -p ../../policies/
5. Evaluate a Single Resource
You can test policies against individual resource JSON:
1
2
3
4
5
6
7
8
9
echo '{
"resource_type": "stackit_compute_instance",
"environment": "production",
"values": {
"name": "web-server-01",
"public_ip": "203.0.113.10",
"region": "eu-central-1"
}
}' | opa eval -d policies/ -I 'data.policies.iaas.network_security.deny'
6. Set Up Pre-commit Hooks
1
2
pip install pre-commit
pre-commit install
Project Structure
1
2
3
4
5
6
7
8
9
10
11
12
13
14
├── policies/
│ ├── iaas/ # IaaS networking and compute policies
│ ├── paas/ # PaaS database and storage policies
│ ├── spring/ # Managed Spring runtime policies
│ └── shared/ # Shared helpers and constants
├── tests/
│ ├── iaas/ # IaaS policy tests
│ ├── paas/ # PaaS policy tests
│ └── spring/ # Spring policy tests
├── terraform/
│ ├── modules/ # Reusable Terraform modules
│ └── environments/ # Per-environment configs (dev, staging, prod)
├── docs/ # Documentation
└── .github/workflows/ # CI/CD pipelines
Writing New Policies
Create a .rego file in the appropriate policies/ subdirectory
Import shared constants and helpers
Add policy metadata with compliance annotations
Write deny rules (hard enforcement) or warn rules (soft enforcement)
Create a corresponding test file in tests/
Run opa fmt -w to format and opa test to verify
Policy Template
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
package policies . < layer > . < policy_name >
import data . shared . constants
import data . shared . helpers
import rego . v1
metadata := {
"id" : "STACKIT-<LAYER>-<ABBREV>-NNN" ,
"description" : "..." ,
"scope" : { "provider" : "stackit" , "layer" : "<layer>" },
"severity" : "critical|high|medium|low" ,
"enforcement" : "hard|soft" ,
"compliance" : {
"bsi_c5" : [...],
"gdpr" : [...],
},
}
deny contains msg if {
# Rule conditions
not helpers . has_valid_exception ( input , "POLICY-ID" )
msg := helpers . violation_msg ( "POLICY-ID" , "severity" , resource_name , "message" )
}
Troubleshooting
OPA tests fail with “undefined” : Ensure the package name in your test file matches <policy_package>_test and imports the policy package correctly.
Conftest finds no policies : Check that the -p flag points to the policies/ directory and that your Rego files have the correct package declarations.
Pre-commit hooks fail : Run opa fmt -w policies/ tests/ to auto-format, then retry.