Blog Series: Enforcing Policy as Code in Terraform (Part 4 of 5)

Sentinel, tfsec, and Checkov

Welcome back to our journey into Policy as Code (PaC) with Terraform!

  • In Part 1, we established the "why" and "what" of PaC.
  • Part 2 explored Terraform's native validation and the need for dedicated tools.
  • Part 3 took us on a deep dive into the versatile Open Policy Agent (OPA) and conftest.

Now, in Part 4, we're broadening our horizons to look at other powerful players in the Terraform PaC landscape: HashiCorp's own Sentinel, and the popular static analysis champions, tfsec and Checkov. These tools offer different approaches and strengths, catering to various organizational needs and workflows.

HashiCorp Sentinel: Integrated Governance for the Terraform Ecosystem

If your organization is invested in HashiCorp Terraform Cloud or Terraform Enterprise, Sentinel is a name you'll encounter frequently. It's HashiCorp's embedded Policy as Code framework, designed for fine-grained, logic-based policy enforcement directly within these platforms.

How Sentinel Works with Terraform Cloud/Enterprise: Sentinel policies are evaluated as an integral part of the run workflow, specifically after a terraform plan has been generated and before the terraform apply stage. This is a crucial point because Sentinel gets access to a wealth of information:

  • The Terraform plan (tfplan): What changes are proposed.
  • The current state (tfstate): What infrastructure currently exists.
  • The configuration (tfconfig): The HCL code itself.
  • Run data (tfrun): Information about the current run.

This rich context allows for highly sophisticated policy decisions.

The Sentinel Policy Language (HSL): Policies are written in HSL (HashiCorp Sentinel Language), which is dynamically typed and designed to be approachable.

  • Imports: You import the data you need, like import "tfplan/v2" as tfplan.
  • Rules: The core logic resides in rule blocks. A main rule determines the policy's pass/fail outcome.
  • Functions & Logic: HSL supports boolean logic, custom functions, and iteration to build complex policies.

Example: Enforcing Mandatory Tags with Sentinel Let's say we want to ensure all AWS EC2 instances have an "Owner" tag.

import "tfplan/v2" as tfplan

# Function to find all EC2 instances being created or updated
find_ec2_instances = func() {
    instances = {}
    for tfplan.resource_changes as address, rc {
        if rc.type is "aws_instance" and
           (rc.change.actions contains "create" or rc.change.actions contains "update") {
            instances[address] = rc
        }
    }
    return instances
}

# Rule to check for the 'Owner' tag
all_instances_have_owner_tag = rule {
    all find_ec2_instances() as _, instance {
        instance.change.after.tags contains "Owner"
    }
}

# Main rule: the policy passes if all instances have the 'Owner' tag
main = rule {
    all_instances_have_owner_tag
}

Policy Management and Enforcement Levels in TFC/TFE:

  • Policy Sets: Policies are grouped into "Policy Sets," often defined in a sentinel.hcl file and stored in a Version Control System (VCS) like Git. TFC/TFE can automatically sync with this VCS.
  • Enforcement Levels: This is a key feature.
    • Advisory: Policy failures log a warning, but the run proceeds. Great for introducing new policies.
    • Soft-Mandatory: Failures halt the run, but authorized users can override. Provides a safety net with flexibility.
    • Hard-Mandatory: Failures halt the run, and no overrides are allowed. For critical, non-negotiable policies.

Sentinel's tight integration makes it a very streamlined PaC solution if you're operating within the HashiCorp commercial ecosystem.

Static Analysis Powerhouses: tfsec and Checkov

While Sentinel (and OPA) often operate on the Terraform plan (the intended state), static analysis tools like tfsec and Checkov primarily inspect your raw Terraform HCL code (the defined state). They are excellent for catching common misconfigurations and security vulnerabilities early.

tfsec: Fast Security Scanning for Terraform

tfsec is an open-source static analysis tool specifically designed to find security misconfigurations in your Terraform code. It's known for its speed and ease of use. (Note: tfsec's development is being consolidated into Aqua Security's Trivy, a broader security scanner).

  • How it Works: tfsec parses your .tf files directly without needing to initialize Terraform or generate a plan. It uses a large library of built-in checks based on security best practices from cloud providers and industry standards.
  • Custom Rules: While it has many built-in rules, you can also define custom checks using JSON, YAML, or even Rego.
  • Focus: Primarily security. Think: "Is this S3 bucket publicly readable?", "Is encryption enabled for this database?".
  • Integration: Ideal for pre-commit hooks and early CI/CD stages for rapid feedback.

Checkov: Comprehensive IaC Scanning

Checkov, by Bridgecrew (now Palo Alto Networks), is another popular open-source static analysis tool. It's broader than tfsec, supporting not just Terraform but also CloudFormation, Kubernetes manifests, ARM templates, and more.

  • How it Works:
    • Static HCL Analysis: Like tfsec, it can scan your raw .tf files.
    • Plan Scanning: Checkov can also analyze the JSON output of a Terraform plan, giving it more context about the final configuration.
    • Graph-Based Policies: A powerful feature is its ability to understand relationships between resources. This allows for more sophisticated checks (e.g., "Is this EC2 instance, which is in a public subnet, also exposed via a security group that allows unrestricted access?").
  • Custom Rules: You can write custom policies in Python or YAML.
  • Focus: Security and compliance, with a vast library of pre-built policies.
  • Integration: CLI, CI/CD, pre-commit hooks, and even IDE extensions.

Why Use Static Analysis Tools?

  • Speed and Simplicity: They are generally very fast and easy to integrate.
  • Rich Built-in Libraries: You get a lot of security and compliance checks out-of-the-box.
  • Early Feedback: Catching issues directly in the HCL means faster remediation by developers.

OPA vs. Sentinel vs. Static Analyzers: A Quick Comparison

  • OPA/Conftest:
    • Pros: Highly flexible (Rego is powerful), general-purpose (use OPA beyond Terraform), vendor-neutral, strong for complex custom logic on plan data.
    • Cons: Steeper learning curve for Rego, requires plan -> JSON conversion step.
  • Sentinel:
    • Pros: Seamless integration with TFC/TFE, rich context (plan, state, config), enforcement levels offer operational flexibility.
    • Cons: Primarily tied to HashiCorp's commercial offerings for full enforcement, HSL is specific to Sentinel.
  • tfsec/Checkov (Static Analysis):
    • Pros: Very fast, easy to set up, extensive built-in security/compliance rules, great for pre-commit/early CI feedback on HCL. Checkov's plan and graph analysis add more depth.
    • Cons: Static HCL analysis might miss context that plan-based tools see. Custom rule logic might be less expressive than full Rego/HSL for very complex scenarios.

Often, these tools aren't mutually exclusive. A layered approach can be very effective:

  1. TFLint (from Part 2/3 context, often paired here): For HCL best practices and basic linting.
  2. tfsec/Checkov: For rapid security and compliance checks on HCL in pre-commit and early CI.
  3. OPA/Conftest or Sentinel: For more complex, custom organizational policies evaluated against the Terraform plan before apply.

Conclusion and What's Next

We've now explored a diverse set of tools for enforcing Policy as Code with Terraform. From the general-purpose power of OPA, to the integrated governance of Sentinel, and the rapid security feedback of tfsec and Checkov, you have multiple avenues to ensure your infrastructure is secure, compliant, and well-managed.

In our final installment, Part 5, we'll bring it all together. We'll discuss best practices for integrating these PaC tools into your CI/CD pipelines, strategies for developing, managing, and versioning your policies, and how to foster a culture that embraces Policy as Code. Stay tuned for the wrap-up!