Terraform Sentinel Policies: A Practical Guide (2025 Edition)
A hands-on guide to writing, testing, and enforcing Sentinel policies in Terraform Enterprise and Terraform Cloud to ensure infrastructure compliance.
📋 Prerequisites
- Access to a Terraform Enterprise or Terraform Cloud (paid tier) account.
- Strong understanding of Terraform configuration language (HCL).
- Familiarity with policy-as-code concepts.
- The Sentinel CLI installed locally for testing.
What You'll Learn
- What Sentinel is and its role in Terraform Cloud/Enterprise.
- The core concepts of the Sentinel language and its imports (tfplan, tfconfig).
- How to write a practical, real-world policy from scratch.
- How to unit test your Sentinel policies using mock data.
- Best practices for managing and scaling your policy-as-code library.
🏷️ Topics Covered
What is Sentinel?
Sentinel is HashiCorp's policy-as-code framework, deeply integrated into Terraform Enterprise and Cloud. It acts as a powerful gatekeeper, allowing you to define fine-grained, logic-based rules that are automatically enforced during Terraform runs. Sentinel ensures that all infrastructure provisioned through Terraform adheres to your organization's specific security, compliance, and operational standards.
🏢 Enterprise & Cloud Feature
Sentinel is available exclusively in Terraform Enterprise and the paid tiers of Terraform Cloud. It is not part of the open-source Terraform CLI.
Sentinel Language Fundamentals
Sentinel policies are written in a purpose-built, declarative language. The most critical component for Terraform is the tfplan import, which gives your policy access to the data within a Terraform plan.
tfplan Import
Provides access to the planned infrastructure changes, allowing you to inspect resources being created, updated, or destroyed before an apply.
tfconfig Import
Provides access to the static configuration files themselves, which is useful for checking provider versions or module sources.
main Rule
The entrypoint for a policy. If the main rule evaluates to true, the policy passes. If it's false, the policy fails and blocks the run.
Writing Your First Sentinel Policies
A Sentinel policy set in Terraform Cloud consists of a configuration file and one or more .sentinel files.
1. Configuration: sentinel.hcl
This file defines which policies to enforce and at what level. The enforcement levels are:
- Hard-mandatory: Must pass. Blocks the run on failure.
- Soft-mandatory: Can be overridden by authorized users.
- Advisory: Creates a warning but does not block the run.
policy "enforce-aws-standards" {
source = "./enforce-aws-standards.sentinel"
enforcement_level = "hard-mandatory"
} 2. Policy: enforce-aws-standards.sentinel
This policy enforces two common rules: restricting EC2 instance types to an approved list and ensuring all instances have an owner tag.
import "tfplan/v2" as tfplan
# Define a list of approved instance types
allowed_instance_types = ["t3.micro", "t3.small", "m5.large"]
# Helper function to find all EC2 instances being created or updated
find_ec2_instances = func() {
return tfplan.filter_attribute_contains(
tfplan.resource_changes, "type", "aws_instance",
)
}
# Rule 1: All instances must have an approved type
instance_types_are_valid = rule {
all find_ec2_instances() as _, instances {
all instances as _, r {
r.change.after.instance_type in allowed_instance_types
}
}
}
# Rule 2: All instances must have an "owner" tag
instances_are_tagged = rule {
all find_ec2_instances() as _, instances {
all instances as _, r {
"owner" in keys(r.change.after.tags)
}
}
}
# Main rule: The policy passes only if both rules above are true
main = rule {
instance_types_are_valid and instances_are_tagged
} Testing Sentinel Policies
Sentinel includes a powerful testing framework that allows you to validate your policies against mock Terraform plan data. Create a test/ directory with your test cases.
Test Case: test/passing_instance.json
This mock file simulates a compliant Terraform plan. We only need to include the parts of the plan our policy actually inspects.
{
"resource_changes": [
{
"type": "aws_instance",
"change": {
"after": {
"instance_type": "t3.micro",
"tags": {
"owner": "dev-team"
}
}
}
}
]
} Test Case: test/failing_instance.json
This mock file simulates a non-compliant plan with a disallowed instance type and a missing tag.
{
"resource_changes": [
{
"type": "aws_instance",
"change": {
"after": {
"instance_type": "m5.24xlarge",
"tags": {}
}
}
}
]
} You can then run the tests using the Sentinel CLI. The command will automatically discover the policies and test cases.
sentinel test Best Practices for Sentinel
💡 Key Takeaways
- Start with Advisory Mode: When rolling out new policies, begin with the
advisoryenforcement level to see their impact without blocking developers. - Write Helper Functions: For complex logic, create reusable functions within your policies to keep the main rules clean and readable.
- Provide Clear Failure Messages: A policy that fails without explaining *why* is frustrating. Add print statements and detailed rule descriptions to help users self-remediate.
- Centralize Your Policies: Store your Sentinel policies in a dedicated version control repository and manage them as a Policy Set in Terraform Cloud.
- Unit Test Everything: Build a comprehensive suite of test cases covering both passing and failing scenarios for every policy you write.