Sentinel Policy as Code for Terraform

Khimananda Oli 9 min read Virtualization
Sentinel Policy as Code for Terraform

By Khimananda Oli | Last reviewed: August 2026

Unchecked infrastructure drift and misconfigured cloud resources remain the primary cause of security incidents and budget overruns in 2026. Implementing Sentinel Policy as Code for Terraform shifts governance left, allowing you to validate configuration against organizational standards before any API call reaches your cloud provider. This approach replaces manual ticket-based approvals with automated, deterministic checks integrated directly into your Infrastructure as Code workflow, ensuring that every deployment is secure, compliant, and cost-aware by default.

Terraform PlanSentinel EvaluationImport tfplan / stateRun .sentinel PoliciesPASS: ApplyFAIL: BlockGovernance Gate in CI/CD Pipeline
Sentinel Policy as Code for Terraform intercepts the plan output to enforce compliance before execution

How does Sentinel Policy as Code for Terraform actually work?

Sentinel operates as an embedded logic engine that sits between your terraform plan and terraform apply stages. Unlike external validation tools that parse static HCL files, Sentinel inspects the binary plan file which contains the full context of proposed changes, existing state, and provider-specific metadata. This distinction matters because many compliance violations only become visible when you understand the delta between current and desired state.

The evaluation process follows a strict sequence. First, your CI pipeline generates a JSON representation of the plan using terraform show -json. Second, the Sentinel CLI or TFC/TFE agent loads this artifact alongside your policy set. Third, each policy executes against the plan data structure, returning a boolean result plus detailed trace logs. Finally, the orchestrator decides whether to proceed based on the aggregate enforcement level of all policies.

  • Hard-mandatory: The pipeline fails immediately if this policy returns false. Use this for critical security controls like preventing public RDS instances.
  • Soft-mandatory: Failures can be overridden by users with specific permissions. Suitable for tagging standards where exceptions exist.
  • Advisory: Warnings appear in logs but never block deployment. Ideal for deprecation notices or best-practice recommendations.

In practice, I recommend starting with advisory policies to establish a baseline without disrupting active development. After two weeks of observing violations, promote stable rules to soft-mandatory and eventually hard-mandatory once teams have adapted their workflows. This graduated approach prevents the "governance shock" that causes developers to bypass automation entirely.

How do you write effective Sentinel policies for cloud compliance?

Writing maintainable Sentinel requires treating policies like production code rather than disposable scripts. Each policy should focus on a single concern, use descriptive naming, and include comprehensive test cases. The language itself is purpose-built for infrastructure validation, offering native imports for Terraform plan structures that eliminate boilerplate parsing logic.

Enforcing instance size limits

A common requirement in Nepal-based startups and global enterprises alike is preventing runaway cloud costs. This policy ensures no EC2 instance exceeds a predefined type whitelist:

import "tfplan/v2" as tfplan

allowed_types = [
    "t3.micro",
    "t3.small", 
    "t3.medium",
    "m5.large",
]

all_instances = filter tfplan.resource_changes as _, rc {
    rc.type is "aws_instance" and
    (rc.change.actions contains "create" or
     rc.change.actions contains "update")
}

violations = filter all_instances as _, instance {
    instance.change.after.instance_type not in allowed_types
}

main = rule {
    length(violations) is 0
}

This pattern uses the filter expression twice: first to isolate relevant resources, then to identify violations. Separating selection from validation makes debugging easier because you can inspect intermediate values during testing. Always target resource_changes rather than raw resources to avoid flagging unchanged infrastructure during routine applies.

Validating mandatory tags

Tagging policies are foundational for cost allocation and audit trails. However, naive implementations fail when tags are inherited from modules or computed dynamically. A resilient approach checks the final planned value:

import "tfplan/v2" as tfplan

required_tags = ["Environment", "Owner", "CostCenter"]

untagged = filter tfplan.resource_changes as _, rc {
    rc.mode is "managed" and
    rc.change.actions contains "create" and
    some rc.change.after.tags as key, _ {
        key in required_tags
    } else true
}

main = rule {
    length(untagged) is 0
}

Note the use of some ... else true syntax. This handles cases where the tags attribute might be null or unknown during planning. Defensive coding in Sentinel prevents false positives that erode trust in your governance layer. For teams managing multi-cloud environments, consider abstracting tag validation into reusable functions imported across AWS, Azure, and GCP policy sets.

Policy Internal StructureImportstfplan / tfstate / tfrunParameters & Listsallowed_types, required_tagsFilter ExpressionsSelect & Validate Resourcesmain = rule { ... }Boolean Outcome + Trace LogReturn Pass / Fail
Anatomy of a Sentinel policy showing data flow from imports through validation to final verdict

Sentinel vs OPA vs Checkov: Which policy tool should you choose?

Selecting the right policy engine depends on your existing ecosystem, team skills, and compliance requirements. While Open Policy Agent (OPA) and Checkov dominate open-source discussions, Sentinel occupies a distinct niche for HashiCorp-centric organizations. Understanding these trade-offs prevents costly rework later. For a broader comparison of policy-as-code approaches including OPA, see our guide on policy enforcement strategies.

CriteriaSentinelOpen Policy Agent (OPA)Checkov
Primary LanguageSentinel (proprietary DSL)Rego (declarative)Python / YAML
Terraform IntegrationNative plan/state access via importsRequires JSON conversion + custom RegoStatic HCL scanning only
State AwarenessFull prior-state + plan deltaPossible but complex to implementNo (static analysis only)
Ecosystem Lock-inHashiCorp TFC/TFE required for v2Vendor-neutral, CNCF graduatedBridgecrew/Palo Alto Networks
Learning CurveModerate (familiar syntax)Steep (paradigm shift to Rego)Low (Python/YAML familiar)
Best ForTerraform Cloud/Enterprise shopsMulti-tool, Kubernetes-heavy stacksQuick security baselines, pre-commit

If your organization already invests in Terraform Cloud or Enterprise, Sentinel delivers the deepest integration with minimal operational overhead. The ability to access workspace variables, run metadata, and prior state natively eliminates entire categories of glue code. However, if you operate a heterogeneous stack spanning Kubernetes admission control, API gateway authorization, and Terraform validation, OPA's universality justifies its steeper learning curve. Checkov remains valuable as a fast local feedback mechanism regardless of your production enforcement choice.

How do you integrate Sentinel into CI/CD pipelines?

Automation transforms Sentinel from a theoretical safeguard into an operational reality. The integration point must occur after plan generation but before any destructive action. In my experience helping teams achieve DevSecOps maturity, the most reliable pattern uses artifact passing between discrete pipeline stages rather than monolithic scripts.

  1. Generate Plan Artifact: Run terraform plan -out=tfplan.binary followed by terraform show -json tfplan.binary > tfplan.json. Store both files as pipeline artifacts.
  2. Fetch Policy Set: Clone your policy repository or download versioned policies from an artifact store. Never embed policies directly in application repos.
  3. Execute Evaluation: Run sentinel test -verbose for unit tests, then sentinel apply -config=sentinel.hcl tfplan.json for enforcement. Capture stdout/stderr separately.
  4. Handle Results: Parse the exit code and JSON output. On failure, post violation details as PR comments or Slack notifications. On success, promote the plan artifact to the apply stage.
  5. Audit Trail: Archive the evaluated plan, policy versions, and Sentinel trace logs to immutable storage. This evidence satisfies SOC 2 and ISO 27001 auditors without manual screenshots.

A critical mistake teams make is running Sentinel against the working directory instead of the serialized plan. The working directory may contain uncommitted changes or stale state that diverges from what will actually execute. Always validate the exact artifact that will be applied. Additionally, pin your Sentinel CLI version and policy set versions explicitly. Floating versions cause non-reproducible builds that undermine audit confidence.

What are common pitfalls when adopting Sentinel at scale?

After guiding multiple organizations through Sentinel adoption, I've observed recurring failure modes that derail initiatives. Avoiding these accelerates time-to-value significantly.

Over-engineering initial policies. Teams often attempt to encode entire well-architected frameworks in week one. Start with three to five high-impact rules covering security boundaries and cost ceilings. Complex composite policies belong in phase two after basic enforcement muscle memory develops.

Neglecting policy testing. Untested policies are liabilities. Every Sentinel policy needs corresponding test fixtures covering pass, fail, and edge cases. The sentinel test command supports table-driven tests similar to Go. Treat policy tests with the same rigor as application unit tests—they guard against regressions when providers update schemas.

Ignoring developer experience. If violation messages are cryptic, developers will resent the tooling. Include remediation guidance directly in error outputs. Instead of "S3 bucket violates policy," return "S3 bucket 'app-assets' lacks server-side encryption. Add 'server_side_encryption_configuration' block with AES256. See internal wiki link."

Missing escape hatches. Legitimate exceptions exist. Build a formal waiver process into your pipeline configuration using soft-mandatory overrides with expiration dates and approval requirements. Without sanctioned exception paths, teams create shadow infrastructure outside governance entirely.

Without SentinelDeveloper submits PR → Manual reviewApply executes → Misconfiguration deployedSecurity incident / Cost spike detectedReactive remediation + Audit findingsWith SentinelDeveloper submits PR → Plan generatedSentinel blocks violations instantlyDeveloper fixes + ResubmitsCompliant deploy + Audit-ready logs
Before and after comparison demonstrating how Sentinel Policy as Code for Terraform prevents production incidents

Implementing Sustainable Governance with Sentinel Policy as Code for Terraform

Successful adoption of Sentinel Policy as Code for Terraform hinges on treating governance as a product served to your engineering teams, not a gate imposed upon them. Start small, measure impact, iterate based on feedback, and gradually expand coverage as trust builds. Document your policy rationale, provide clear remediation paths, and maintain open channels for exception requests. When implemented thoughtfully, Sentinel becomes invisible infrastructure that protects your organization while preserving developer autonomy. Ready to harden your Terraform workflows or need help designing a compliance framework tailored to your environment? Reach out to discuss your infrastructure governance strategy.

Frequently Asked Questions

Sentinel is a policy-as-code framework embedded in Terraform Cloud and Enterprise that enforces compliance, security, and operational standards before infrastructure changes are applied. Policies are written in the Sentinel language and evaluated during plan or apply phases to block non-compliant resource configurations automatically.

Sentinel integrates natively with Terraform Cloud and accesses internal state and plan data directly without external adapters. OPA Rego requires separate tooling like conftest or tfsentinel and lacks native access to Terraform workspace metadata, making Sentinel more tightly coupled but less portable across non-Terraform platforms.

No. Sentinel requires Terraform Cloud Business tier or Terraform Enterprise. Open source users must rely on alternatives like OPA, Checkov, or tfsec for policy enforcement since Sentinel runtime and standard libraries are proprietary and only distributed through HashiCorp commercial offerings.

Use the sentinel CLI with the test command against mock JSON plan files generated via terraform show -json. Define test cases in .sentinel files using test blocks to validate pass, fail, and advisory outcomes without requiring a live Terraform Cloud workspace or API token.

Yes. Sentinel policies can import the tfstate/v2 module to query current resource attributes, counts, and dependencies. This enables drift detection, tagging audits, and compliance checks based on deployed infrastructure rather than just proposed changes in the execution plan.

Organization owners manage policy sets and assign them to workspaces. Workspace-level enforcement modes (advisory, soft-mandatory, hard-mandatory) determine whether violations warn or block applies. Team-based access controls restrict who can create, edit, or override policies using Terraform Cloud RBAC and team tokens.

Import tfplan/v2 and iterate over all resources using filter expressions. Check that required tags like Environment and Owner exist and match allowed values. Return false if any resource lacks mandatory tags, triggering a hard-mandatory violation that prevents apply until corrected.

Yes. You can define reusable functions in .sentinel files and organize them into modules imported via relative paths or Git repositories. Custom modules reduce duplication across policies and centralize logic for common checks like CIDR validation, naming conventions, or cost threshold evaluations.

Terraform Cloud returns structured JSON output listing violated rules, severity levels, and affected resources. CI systems parse this output to fail builds, post comments to pull requests, or trigger notifications. Advisory violations log warnings without blocking, while hard-mandatory failures halt pipeline progression immediately.

Yes. Write a policy importing aws/s3-bucket/v1 that checks acl and public_access_block_configuration attributes. Deny plans where ACL equals public-read or public-read-write, or where block_public_acls is false. Combine with soft-mandatory mode to allow overrides only with documented justification and approval.

Minimal. Policy evaluation occurs after plan generation and typically completes in under two seconds for standard rule sets. Complex policies iterating over thousands of resources may add latency, so optimize loops, use early exits, and avoid redundant imports to maintain fast feedback cycles.

Use suppression comments with # suppress: above specific resource blocks in HCL when exceptions are justified. Alternatively, configure policy set parameters to exclude certain workspaces, tags, or resource types. Always document override reasons in VCS commits for auditability and team alignment.

Not directly. Sentinel evaluates infrastructure configuration, not file contents or secrets. Pair it with tools like TruffleHog or git-secrets in pre-commit hooks or CI stages. Use Sentinel to enforce that resources reference vault-backed variables instead of hardcoded strings, complementing secret scanning with preventive guardrails.

Yes. Write provider-agnostic policies using generic resource iteration and metadata filters, or maintain separate policy sets per cloud provider. Standard libraries exist for AWS, Azure, GCP, and Kubernetes. Centralize shared logic in custom modules to ensure consistent tagging, networking, and encryption standards across clouds.

Quarterly at minimum, or whenever cloud provider APIs change, new compliance requirements emerge, or incident postmortems reveal gaps. Track policy version history in VCS, tie updates to RFCs or change tickets, and validate backward compatibility using regression tests before deploying modified policy sets to production workspaces.