HashiCorp : Terraform Cloud
Policy as Code Sentinel and OPA
Lab Solution Terraform Cloud Sentinel Policy
In this lab, we’ll implement Policy as Code in Terraform Cloud with Sentinel. Sentinel enforces organizational policies between the terraform plan
and terraform apply
stages, ensuring your infrastructure remains compliant before changes are applied.
Prerequisites: Teams & Governance Tier
Sentinel policies require the Teams & Governance tier in Terraform Cloud. In Settings → Plan & Billing, activate your free trial or subscription for this tier to unlock Policy as Code, cost estimation, and run tasks.
Note
You must have an active Teams & Governance plan in Terraform Cloud before you can enforce Sentinel policies.
In Plan & Billing you’ll see your current plan:
The Teams & Governance tier includes all Team features plus Policy as Code and additional run capabilities:
Fork the Sentinel Policy Repository
Start by forking the HashiCorp Sentinel policy repository into your GitHub account. This gives you a local copy to customize and connect to Terraform Cloud.
Review Sentinel Policies
Below are two example policies from the repository.
1. Enforce Mandatory Tags
This policy uses the tfplan-functions
import to require that every AWS EC2 instance in the plan has a Name
tag. The main
rule fails if any instance is missing this tag.
import "tfplan-functions" as plan
# Tags that must be present on every EC2 instance
mandatory_tags = ["Name"]
# Gather EC2 instances from the plan
allEC2Instances = plan.find_resources("aws_instance")
# Identify instances missing required tags
violatingEC2Instances = plan.filter_attribute_not_contains_list(
allEC2Instances, "tags", mandatory_tags, true
)
# Fail the policy if any violations exist
main = rule {
length(violatingEC2Instances["messages"]) is 0
}
2. Restrict EC2 Instance Types
This policy ensures only specific EC2 instance types (t2.micro
, t2.small
, t2.medium
) are allowed. Any other type triggers a violation.
import "tfplan-functions" as plan
# List of approved EC2 instance types
allowed_types = ["t2.micro", "t2.small", "t2.medium"]
# Gather EC2 instances from the plan
allEC2Instances = plan.find_resources("aws_instance")
# Find instances with disallowed types
violatingEC2Instances = plan.filter_attribute_not_in_list(
allEC2Instances, "instance_type", allowed_types, true
)
# Count how many violations we have
violations = length(violatingEC2Instances["messages"])
# Enforce zero violations
main = rule {
violations is 0
}
Define a Policy Set
Group your Sentinel policies in a sentinel.hcl
file at the repository root. Specify each policy and its enforcement level:
module "tfplan-functions" {
source = "https://raw.githubusercontent.com/hashicorp/terraform-guides/master/governance/third-generation/common-functions/tfplan-functions/tfplan-functions"
}
module "tfconfig-functions" {
source = "https://raw.githubusercontent.com/hashicorp/terraform-guides/master/governance/third-generation/common-functions/tfconfig-functions/tfconfig-functions"
}
policy "enforce-mandatory-tags" {
enforcement_level = "advisory"
}
policy "restrict-ec2-instance-type" {
enforcement_level = "hard-mandatory"
}
Enforcement levels determine how Sentinel handles violations:
Enforcement Level | Behavior |
---|---|
advisory | Emits a warning but does not block the run |
soft-mandatory | Blocks runs unless an admin override is added |
hard-mandatory | Strictly enforces the policy; no bypass allowed |
Warning
The hard-mandatory level cannot be bypassed. Any violation will block the run.
Connect the Policy Set to Terraform Cloud
- In Terraform Cloud, go to Settings → Policy sets.
- Click Connect new policy set, select GitHub (or your VCS), then choose your fork.
- Set Policy framework to Sentinel, give it a name (e.g., “AWS Global Policies”), add a description, and specify the path:
terraform-cloud/policy-as-code/sentinel/global
- Apply to All workspaces.
- Click Connect policy set.
Test Policy Enforcement in the UI
Trigger a new run in your workspace. After the plan stage, you’ll see Policy check:
Policy results appear in the run output:
## Policy 1: AWS-Global-Policies/enforce-mandatory-tags (advisory)
Result: true
Description:
This policy uses the Sentinel tfplan import to require that all EC2 instances have all mandatory tags.
## Policy 2: AWS-Global-Policies/restrict-ec2-instance-type (hard-mandatory)
Result: true
Description:
This policy uses the Sentinel tfplan/v2 import to require that all EC2 instances have instance types from an allowed list.
Test Policy Enforcement via CLI
- Configure your backend for Terraform Cloud and run
terraform login
. - Change the
instance_type
interraform.auto.tfvars
to an unapproved value (e.g.,"m5.large"
). - Execute:
terraform init terraform plan
This triggers a remote run with policy checks. Violations will block the plan.
## Policy: AWS-Global-Policies/restrict-ec2-instance-type (hard-mandatory)
Result: false
Description:
aws_instance.clumsy_bird has instance_type with value m5.large that is not in the allowed list: [t2.micro, t2.small, t2.medium]
Error: Organization Policy Check hard failed.
Remediate and Re-Run
Update your terraform.auto.tfvars
to a compliant instance type and commit:
# terraform.auto.tfvars
prefix = "app"
project = "clumsy-bird"
environment = "development"
instance_type = "t2.medium"
git add terraform.auto.tfvars
git commit -m "Set instance_type to t2.medium"
git push
Terraform Cloud will automatically start a new run and, if compliant, proceed to apply:
## Policy 2: AWS-Global-Policies/restrict-ec2-instance-type (hard-mandatory)
Result: true
Description:
This policy uses the Sentinel tfplan/v2 import to require that all EC2 instances have instance types from an allowed list.
Additional Resources
Terraform Public Registry – Policy Library (Beta): Terraform Public Registry Policy Library (Beta)
AWS Networking Policies in Terraform Guides: AWS Networking Sentinel Policies for Terraform Guides
HashiCorp Terraform Guides Repository: HashiCorp Terraform Guides Repository
Sentinel Policy Updates History: Commit History
In this guide, we covered how to store Sentinel policies as code, connect them to Terraform Cloud, and enforce them via both the UI and CLI. With Sentinel policies running automatically between plan and apply, you can enforce organizational standards for every infrastructure change.
Watch Video
Watch video content
Practice Lab
Practice lab