Assume you have generated a new rule, CUSTOM-RULE-1 using the SDK , that is, snyk-iac-rules template --rule CUSTOM-RULE-1 and have a very simple fixture file containing a Terraform resource:
Now, modify the generated Rego to enforce resources tagged with an owner:
Create a variable [name] to enumerate across all of the aws_redshift_cluster resources. This variable can be named anything you like, for example, i, j, name, and so on.
Store this into the resource variable by assigning the value to it with a walrus operator :=; e.g. resource := input.resource.aws_redshift_cluster[name]
Check whether the owner tag exists for each resource; to do that, check if the path resource.tags.owner is defined. If it is undefined, it will evaluate as undefined. So, use the NOT keyword in front of it, which will evaluate to TRUE; for example,not resource.tags.owner
The test for this rule will look the same as the one for CUSTOM-RULE-1, but the name of the test and the first two arguments passed to the testing.evaluate_test_cases function will differ:
rules/CUSTOM-RULE-2/main_test.rego
package rules
import data.lib
import data.lib.testing
test_CUSTOM_RULE_2 {
# array containing test cases where the rule is allowed
allowed_test_cases := [{
"want_msgs": [],
"fixture": "allowed.tf",
}]
# array containing cases where the rule is denied
denied_test_cases := [{
"want_msgs": ["input.resource.aws_redshift_cluster[denied].tags"],
"fixture": "denied.tf",
}]
test_cases := array.concat(allowed_test_cases, denied_test_cases)
testing.evaluate_test_cases("CUSTOM-RULE-2", "./rules/CUSTOM-RULE-2/fixtures", test_cases)
}
Example with logical OR
You can also rewrite the rule above by combining the NOT operator with the OR functionality.
Update the example in a new rule CUSTOM-RULE-3, to deny all cases that fail either of the two conditions, to deny all aws_redshift_cluster resources that are missing either:
an “owner” tag , OR
A “description” tag
For this, use two new fixture files, one for each case: