How do you enforce security and compliance checks before running terraform apply?
Quick Answer
Enforce pre-apply checks using policy-as-code tools: Sentinel policies in Terraform Cloud/Enterprise for hard/soft-mandatory rules, OPA/Conftest for open-source policy evaluation against terraform plan JSON output, and Checkov/tfsec for static analysis of HCL files in CI. All checks run during terraform plan in the CI pipeline and block apply if violations are found.
Detailed Answer
Think of a building permit process. Before construction (terraform apply) begins, inspectors (policy tools) review the blueprints (terraform plan) for code violations, fire safety issues, and zoning compliance. No permit means no construction. The inspectors do not do the building — they only verify that the plans meet standards before the builder starts work.
Security and compliance checks in Terraform operate at three layers. Static analysis (pre-plan) scans HCL source code for known bad patterns like unencrypted S3 buckets, public security groups, or missing tags. Tools like Checkov, tfsec, and Trivy scan .tf files directly in CI and fail the pipeline if violations are found. This catches issues before Terraform even generates a plan.
Plan-time policy evaluation (post-plan, pre-apply) is the most powerful layer. terraform plan -out=plan.tfplan generates a plan file, then terraform show -json plan.tfplan converts it to JSON. This JSON contains the exact changes Terraform will make — resources to create, modify, or destroy with all their attributes. Policy tools like OPA/Conftest or Sentinel evaluate this JSON against rules: 'no security group may have ingress from 0.0.0.0/0', 'all RDS instances must have encryption enabled', 'no resource may be destroyed in the prod workspace without approval.' If any policy fails, the pipeline blocks apply.
In Terraform Cloud/Enterprise, Sentinel policies are built-in. Policies are categorized as advisory (warning only), soft-mandatory (can be overridden by authorized users), or hard-mandatory (cannot be overridden). This three-tier approach lets teams enforce critical security rules strictly while allowing flexibility for less critical standards. Cost estimation is also available, alerting when a plan would increase monthly spend beyond a threshold.
The non-obvious gotcha is that static analysis alone misses context-dependent violations. A security group rule allowing 0.0.0.0/0 on port 443 is fine for a public ALB but dangerous for an RDS instance. Plan-time policy evaluation sees the full resource context (what type of resource, what VPC, what tags) and can make smarter decisions. Teams should use both layers: static analysis for quick feedback during development, and plan-time policies for authoritative enforcement before apply. Also, policy tests are code too — version them in Git, review them in PRs, and test them against sample plans.