Rego is the language used by the Open Policy Agent. I use it in Conftest for infrastructure testing. Together, they’re great for writing policies that enforce requirements in things like Terraform HCL and Kubernetes YAML. Check out the conftest usage guide for an example.

In Rego, you write rules that check if data structures look the way you expected. Rules are kind of like functions in Python. They contain the logic you write.

Two rules can have the same name. The way Rego handles that surprised me. I wrote some bugs before I got used to it.

In Python, if two functions have the same name:

```
def f1():
return 'first'
def f1():
return 'second'
print(f1())
```

The second function gets executed:

```
python ./test.py
second
```

In Rego, the value of a rule is a set containing the values of all the rules that have the same name.

If we use the Rego Playground to evaluate this rule:

```
even_or_odd[value] {
contains(input.message, "one")
value := "odd"
}
```

With this input:

```
{
"message": "one two three"
}
```

We get a set with one value:

```
{
"even_or_odd": [
"odd"
]
}
```

We can confirm it’s a set with the built-in `is_set`

function in a new rule:

```
even_or_odd[value] {
contains(input.message, "one")
value := "odd"
}
even_or_odd_is_set[value] {
value := is_set(even_or_odd)
}
```

This evaluates to:

```
{
"even_or_odd": [
"odd"
],
"even_or_odd_is_set": [
true
]
}
```

If we add another rule that’s also named `even_or_odd`

and that has a new value:

```
even_or_odd[value] {
contains(input.message, "one")
value := "odd"
}
even_or_odd[value] {
contains(input.message, "two")
value := "even"
}
```

We get the new value in the `even_or_odd`

set:

```
{
"even_or_odd": [
"even",
"odd"
]
}
```

Sets contain unique values, so if we add a new rule with an old value:

```
even_or_odd[value] {
contains(input.message, "one")
value := "odd"
}
even_or_odd[value] {
contains(input.message, "two")
value := "even"
}
even_or_odd[value] {
contains(input.message, "three")
value := "odd" # This value already exists in the set.
}
```

We get the same two values (not a third):

```
{
"even_or_odd": [
"even",
"odd"
]
}
```

These are small details, but they weren’t obvious to me when I started. Hopefully they save you some troubleshooting.

*You might also want to check out these articles:*