Book a 90-minute product workshop led by HashiCorp engineers and product experts during HashiConf Digital Reserve your spot

Enforce Policy with Sentinel [Team & Governance]

team & governance

The Sentinel Language in Terraform Cloud

Let's start by looking at a real Sentinel policy:

hour = 4
main = rule { hour >= 0 and hour < 12 }

This first line of this example declares a variable named hour with the value 4. The second line declares a rule that will return true if hour is between 0 and 12.

This policy can be applied using Sentinel CLI to determine whether this policy passed or failed. Save this file as policy.sentinel and run the Sentinel CLI against it.

$ sentinel apply policy.sentinel

You should receive an output of Pass from this command.

This example introduces a core concept of Sentinel; Rules. Rules are the primary definitions within a policy. Rules are boolean operators that evaluate whether a statement is true or false. The result of a rule can be used to determine whether or not a Terraform action can execute. We'll look more at rules and how they function.


All policies need a main rule. This is the rule that that defines the final output of Pass or Fail in Sentinel. Let's take a look at more complex rule:

import "tfplan"

main = rule {
  all tfplan.resources.aws_instance as _, instances {
    all instances as _, r {
      r.applied.tags else null is not null

This policy has several more rules than our previous example. We won't check this in Sentinel CLI yet, but let's break down the structure of this rule to understand the Sentinel language logic.

»Building Policies

At the core of a policy, Sentinel evaluates factors from defined conditions and imported data to two possible outcomes: Pass or Fail. These conditions are defined with variables and operators. Sentinel can parse variables of several different types. First, are the basic comparisons:

!=not equal
<=less or equal
>=greater or equal
is notnot equal

These operators can evaluate basic variables like strings and integers. Sentinel can also evaluate with conditions like contains, in, and matches.

main = rule {
  all tfplan.resources.aws_instance as _, instances {
    all instances as _, r {
      r.applied.tags else null is not null

Our main rule here searches for all aws_instance resources within the tfplan import. Any matching instances are then scanned for the tags attribute.

Our main rule depends on the tfplan import which we will go over in another section. The tfplan import must contain at least one aws_instance resource. All aws_instance resources are then evaluated to see if there is at least one tag attribute applied.

r.applied.tags else null is not null is the evaluation that determines the outcome.

If the instances all contain tags, the policy passes. If the instances do not contain tags, the policy fails.