I am very new to OPA but testing something very simple. I would like to create a policy to ensure my s3 is not public.
my simple TF file:
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "4.64.0"
}
}
}
provider "aws" {}
resource "aws_s3_bucket" "test" {
bucket = "test"
# acl = "private"
acl = "public-read"
tags = {
Name = "test"
}
}
My rego file, got it from https://github.com/Scalr/sample-tf-opa-policies/blob/master/aws/enforce_s3_private.rego
# Check S3 bucket is not public
package terraform
import input.tfplan as tfplan
deny[reason] {
r = tfplan.resource_changes[_]
r.mode == "managed"
r.type == "aws_s3_bucket"
r.change.after.acl == "public"
reason := sprintf("%-40s :: S3 buckets must not be PUBLIC",
[r.address])
}
MY TF commands to get the plan and json to test the rego policy:
terraform init
terraform plan --out -no-color tfplan.output
terraform show -json tfplan.output | jq ".resource_changes | map ({(.type|tostring) : .}) | add" > tfplan.json
Now I would like to test my rego policy and bumping here as the terminal hangs. I don't know if I am using the right command or if my rego policy is missing something:
opa eval --data s3-validate.rego --input tfplan.json --stdin
I would appreciate some help.
I have made a simplified example here based on your example. The input file doesnt really matter in this example.
package terraform
import input.tfplan as tfplan
deny[reason] {
r = [{"name": "foo", "a": 1}, {"name": "bar", "a": 2}][_]
r.a > 1
reason := sprintf("%-40s :: S3 buckets must not be PUBLIC",
[r.name])
}
In this example I have two results and I want to capture any that have the attribute greater than 1.
Now your question you have stated eval
. This is used when you want to evaluate things. So we can do that with
$ opa eval --data example.rego --input input.json "data.terraform.deny"
{
"result": [
{
"expressions": [
{
"value": [
"bar :: S3 buckets must not be PUBLIC"
],
"text": "data.terraform.deny",
"location": {
"row": 1,
"col": 1
}
}
]
}
]
}
However generally when running policy you would want to use exec
$ opa exec --bundle . --decision "terraform/deny" input.json
{
"result": [
{
"path": "input.json",
"result": [
"bar :: S3 buckets must not be PUBLIC"
]
}
]
}
Since I am not sure what your intention is here I have listed both. You can read more on terraform examples https://www.openpolicyagent.org/docs/latest/terraform/#4-evaluate-the-opa-policy-on-the-terraform-plan