Are there limitations on expressions in the rule scope? "all" and "if" have issues in/out of rules scope

I’ve been trying to learn Sentinel using the example code in https://www.hashicorp.com/blog/announcing-vcs-enabled-versioned-policy-sets-in-hashicorp-terraform-enterprise

In particular I have been trying to use the example

# Enforces each pet name to have at least three words.

import "tfconfig"

main = rule {
    all tfconfig.resources.random_pet as _, pet {
       pet.config.length >= 3
    }
}

But I am encountering issues with scope when I try to do simple modifications it for more advance cases

** Issue No 1: all expression can’t be used in a function?**

https://docs.hashicorp.com/sentinel/language/spec#any-all-expressions

import "tfconfig"

check_length = func() {
  all tfconfig.resources.random_pet as _, pet {
    pet.config.length >= 3
  }
}

validate = check_length()

main = rule {
  check_length()
}

When I run it in the simulator 0.10.3, I get the error
demo-pets-length.sentinel:5:3: expected statement, found 'all' (and 1 more errors)

Issue No. 2: I cannot use if statements in a main rule?

value = 2
main = rule {
  if value == 3 {
    false
  }
}

I instead get the error expected operand, found 'if'

Sorry if this seems to be putting 2 issues into one topic. My main question is can we get clarification of what expression are valid in the “rule” scope?

Hey Shih!

You can use all in a function, but you’d want:

check_length = func() {
	return all tfconfig.resources.random_pet as _, pet {
		pet.config.length >= 3
	}
}

Note the return statement.

any and all are expressions in their own right, which is why they work naturally in rules, which expect expressions. They aren’t statements, which is why you need use it with return in a function.

That leads me to the second answer: you can’t use statements in a rule, only expressions.

So you can’t use if in a rule, you have to just use the boolean expression:

main = rule { value is 3 }

So ultimately, to answer the last question:

can we get clarification of what expression are valid in the “rule” scope?

Expressions are valid in a rule, but statements are not:

  • if, for, and assignments (example: foo = bar) are examples of statements. They are not allowed.
  • Binary expressions (ie: foo is bar, a + b, etc), and the loop-like any and all are examples of expressions. These are allowed.
  • The final expression in a rule must resolve to a boolean. So while you could mix arithmetic and what not in a rule expression, the final result must be a boolean, ie 2 + 3 is 5.
  • Function calls are expressions as well, so if you want some complexity in your rule, you can spin it off into a function, ie: add(2, 3) is 5.

More info from the spec:

Also take a look at Rules from the Sentinel docs, which gives a good breakdown on how rules work.

Hope this helps!

1 Like

Thank you very much for that detailed explanation. That has helped a lot. I had read about the Expressions and Statements docs. But I must have just missed the section specific to the Rules construct

2 Likes