Sample terraform with a resource that we'd like to catch
# main.tf
resource "null_resource" "default" {
provisioner "local-exec" {
command = "sh -c 'echo hi'"
}
}
Then convert the terraform to json using hcl2json
hcl2json main.tf > main.tf.json
Then write this rego policy to deny if the json terraform contains a denied resource
# deny_resource_types.rego
package resource_types
import future.keywords.in
denied_resource_types = [
"null_resource",
]
deny["you shall not pass"] {
some rtype in denied_resource_types
count(input[_][rtype]) > 0
}
Finally, run opa test to verify the deny
opa eval \
--data deny_resource_types.rego \
--input main.tf.json \
--fail-defined \
"data.resource_types.deny"
{
"result": [
{
"expressions": [
{
"value": [
"you shall not pass"
],
"text": "data.resource_types.deny",
"location": {
"row": 1,
"col": 1
}
}
]
}
]
}
This returns you shall not pass
returned because more than zero banned resources appear. This results in a non-zero code since the --fail-defined
flag is added to opa
.
- https://www.openpolicyagent.org/docs/latest/policy-reference/
- https://www.scalr.com/blog/opa-series-part-2-opa-logic-and-structure-for-scalr
- https://spacelift.io/blog/what-is-open-policy-agent-and-how-it-works
- https://www.openpolicyagent.org/docs/latest/terraform/
- https://blog.gruntwork.io/automatically-enforce-policies-on-your-terraform-modules-using-opa-and-terratest-d6a3f34330a1