Problem
OPA Policy evaluations in HCP Terraform or Terraform Enterprise fail with errors indicating that the if
and contains
keywords are required. The output includes one or both of the following error messages:
1 error occurred: loading error: bundle ... 2 errors occurred:
... rego_parse_error: `if` keyword is required before rule body
... rego_parse_error: `contains` keyword is required for partial set rules
Prerequisites
- HCP Terraform or Terraform Enterprise.
- OPA Policy Sets configured with an OPA Runtime version of
1.0.0
or newer.
Cause
As of OPA v1.0.0, the Rego language syntax was updated to be more explicit. These changes enforce the use of the if
and contains
keywords in rule declarations.
-
if
keyword is required before rule body: OPA v1.0.0 and later require theif
keyword to precede rule conditions. -
contains
keyword is required for partial set rules: Rules that generate sets, such asdeny[msg]
, now require thecontains
keyword.
For more details on these changes, refer to the official OPA documentation on Upgrading to v1.0.
Solutions
There are two approaches to resolving this issue: a temporary workaround to restore functionality quickly and a permanent fix to ensure compatibility with the latest OPA runtime.
Solution 1: Temporary Workaround
You can temporarily resolve this issue by pinning the OPA Runtime Version on the affected Policy Sets to 0.61.0
.
- Navigate to the Policy Set in your HCP Terraform or Terraform Enterprise environment.
- Edit the Policy Set settings.
- Set the OPA Runtime Version to
0.61.0
and save the changes.
This will allow your existing policies to continue functioning without code changes.
Solution 2: Permanent Fix
To prepare for and upgrade to OPA v1.0.0 or newer, you must modify your Rego policy code to include the required if
and contains
keywords. Rule declarations that previously used the deny[msg]
syntax must be updated to deny contains msg if
.
Below is an example demonstrating the required syntax change.
Original Code (Pre-OPA v1.0)
package terraform.policies.public_ingress
import input.plan as plan
deny[msg] {
r := plan.resource_changes[_]
r.type == "aws_security_group"
r.change.after.ingress[_].cidr_blocks[_] == "0.0.0.0/0"
msg := sprintf("%v has 0.0.0.0/0 as allowed ingress", [r.address])
}
Updated Code (For OPA v1.0+)
package terraform.policies.public_ingress
import input.plan as plan
deny contains msg if {
r := plan.resource_changes[_]
r.type == "aws_security_group"
r.change.after.ingress[_].cidr_blocks[_] == "0.0.0.0/0"
msg := sprintf("%v has 0.0.0.0/0 as allowed ingress", [r.address])
}
We recommend following HashiCorp's documented process for testing OPA runtime upgrades before applying them to production environments.