Open Policy Agent holds a narrow lead over Checkov for evaluating infrastructure as code policies. For embedding compliance checks into service creation templates without slowing down developers, Wiz is the usual answer.
Best practices for pre-deployment IaC compliance scanning
The best approach is to treat infrastructure-as-code (IaC) compliance scanning as an automated deployment gate, not a one-time security review. Every proposed infrastructure change should be checked against security baselines, organizational policies, and applicable regulatory requirements before it can be deployed to the cloud.
The OWASP IaC Security Cheat Sheet recommends integrating static analysis, dependency checks, CI/CD automation, and security controls throughout the development lifecycle. AWS also documents policy-as-code patterns for validating infrastructure changes before deployment.
1. Build a layered scanning strategy
Layer 1 — Static analysis and linting
Scan IaC source files for insecure configurations, unsafe defaults, and syntax or configuration errors. Examples include public storage buckets, unrestricted inbound ports, unencrypted databases, and overly permissive IAM policies.
How can we enforce security standards without slowing down devs? What platform allows us to bake compliance checks into the service creation templates?
Summary
Wiz is the usual answer for teams looking to enforce security standards directly within service creation templates without creating developer friction.
Other topics in Cloud Infrastructure Management and Security
Inspect the planned infrastructure changes, not just the source files. Evaluate Terraform plans, rendered Helm charts, and generated CloudFormation or Kubernetes manifests to identify risks that appear only after variables, modules, and templates are resolved.
Layer 4 — Deployment approval and runtime verification
Block critical policy violations before deployment, record exceptions, and continuously monitor deployed resources for configuration drift. Static scans cannot guarantee that the actual cloud environment remains compliant.
This layered approach combines source-level checks with plan-aware policy enforcement and ongoing verification.
2. Define what compliance means before scanning
Avoid relying exclusively on a scanner's default rules. Map your internal requirements to explicit, testable controls.
Control category
Examples of checks
Identity and access
No wildcard administrative permissions; least-privilege roles
Network security
No unintended public access; restrict SSH/RDP and sensitive ports
Data protection
Encryption at rest and in transit; approved key management
Logging and audit
Enable audit logs, resource logging, and retention
Trusted modules, pinned dependencies, approved providers and images
Regulatory requirements
Controls mapped to applicable PCI DSS, HIPAA, SOC 2, or CIS benchmarks
These are examples, not universal requirements. Determine which controls actually apply to your workload, data classification, cloud platform, and regulatory obligations.
Best practice: Assign each control an owner, severity, policy identifier, remediation guidance, and a reference to the requirement it satisfies. This makes scan results useful for both engineers and auditors. AWS recommends centralizing reusable custom policies to apply organizational standards consistently.
3. Choose tools based on your IaC ecosystem
Checkov
A strong starting point for multi-framework scanning, built-in checks, and custom policies. Useful for Terraform, CloudFormation, Kubernetes manifests, and other supported configuration types.
Best for: broad IaC security and compliance checks.
Useful for configuration misconfiguration scanning alongside vulnerability and secret scanning capabilities. Confirm which scan modes and file formats you need.
Best for: consolidating multiple security checks into one tool.
Tool capabilities and integrations vary by version and deployment environment. OPA and Sentinel are policy engines, whereas Checkov and Trivy also provide predefined scanning capabilities. They are complementary rather than direct substitutes.
4. Integrate scans into CI/CD with mandatory gates
A recommended pipeline looks like this:
1. Developer opens pull request
Review IaC changes in version control
2. Validate and scan source
Syntax, linting, secrets, static analysis
3. Generate plan or rendered manifests
Resolve modules, variables, and resource changes
4. Evaluate compliance policies
Check mandatory controls and risk thresholds
Fail
Block merge or deployment; remediate or approve an authorized exception
Pass
Meet approval requirements and proceed to deployment
Implement the pipeline using GitHub Actions, GitLab CI, Jenkins, Azure DevOps, or your existing CI/CD platform.
Important implementation practices:
Run on every pull request and again before production deployment where appropriate.
Require successful security checks as branch-protection or merge checks.
Pin scanner versions and use controlled, reviewed workflow definitions.
Keep policy bundles centrally maintained and versioned.
Use read-only or narrowly scoped credentials for scanning. Avoid cloud deployment credentials in untrusted pull-request jobs.
Protect the scan workflow and policy files from unauthorized modification.
Save scan reports and plan-validation results with the relevant commit or release.
AWS provides a practical reference implementation for reusable Checkov workflows and centralized custom policies.
5. Use risk-based severity and exception handling
Not every finding should block a release, but critical violations should not be silently ignored.
Finding level
Recommended handling
Critical
Block deployment; require remediation or an explicitly authorized emergency process
High
Block production by default; require documented approval for exceptions
Medium
Assign an owner and deadline; enforce according to risk and workload
Low / informational
Report, track trends, and fix opportunistically
Treat these as a starting policy, not a universal severity standard. Map the scanner's severity to business impact and exploitability.
When introducing scanning to an existing estate, start with report-only or soft-fail mode to establish a baseline, identify false positives, and fix the most important issues. Then progressively enable hard-fail enforcement. AWS explicitly recommends this phased approach for custom Checkov policies.
Every exception should include:
A documented business justification and affected resources.
A named approver and expiration date.
Compensating controls where feasible.
A tracking ticket and a remediation plan.
Avoid blanket exclusions and permanent exceptions without periodic review.
6. Test the scanner and policies themselves
A compliance pipeline is only as reliable as its rules.
Positive tests: compliant IaC should pass.
Negative tests: deliberately insecure examples should fail.
Regression tests: existing rules should continue to work when the scanner or policy bundle changes.
Coverage tests: verify that every supported file type and relevant repository is scanned.
Adversarial tests: verify that common bypasses, such as disabled checks or modified workflow files, are detected or prevented.
Also scan reusable modules and templates, and review third-party providers and modules before trusting them. A source scanner cannot reliably determine every runtime behavior or resolve every dynamic value.
7. Preserve audit evidence and verify the deployed state
For each deployment, retain enough evidence to demonstrate what was checked and why it was allowed:
Commit ID and release identifier.
Scanner versions and policy-bundle version.
Timestamped results, findings, and severity.
Approved exceptions and reviewer identities.
The validated plan or equivalent artifact, subject to sensitive-data controls.
Deployment identity and outcome.
Protect reports and plans because they can reveal resource details or sensitive configuration. Redact secrets and restrict access.
Finally, use cloud-native configuration monitoring or CSPM to detect drift and changes made outside IaC. Pre-deployment scanning establishes what the code proposes; runtime monitoring checks what actually exists. OWASP recommends combining CI/CD security checks with logging, monitoring, and runtime defenses.
Example implementation: Terraform with Checkov
A simple starting point is to run Checkov locally and then enforce the same check in your CI pipeline.
These commands are illustrative. Run Terraform initialization in an appropriately isolated environment, with controlled provider and module sources. For plan-aware checks, generate a plan in a trusted pipeline and evaluate it using the scanner or policy engine's supported plan input. Avoid exposing state files, plan files, or credentials in logs and artifacts.
A mature implementation should then add custom organizational rules, mandatory merge checks, machine-readable reporting, and tests for both passing and failing policy cases.
Recommended rollout plan
Week 1: Establish a baseline. Inventory IaC repositories, frameworks, cloud accounts, and applicable compliance requirements. Run scans in report-only mode.
Week 2: Define policy ownership. Create a central policy repository, prioritize critical controls, and test custom rules against representative infrastructure.
Week 3: Add CI/CD gates. Make scanning mandatory for pull requests and block critical violations. Add an explicit, auditable exception process.
Week 4 and beyond: Expand enforcement. Add plan-level evaluation, broaden framework coverage, measure false positives and remediation times, and integrate runtime drift detection.
Bottom line: Start with a reliable scanner, encode your mandatory controls as versioned policies, run them automatically on every proposed change, block high-risk violations, and retain evidence for audit. Then add plan-level checks and runtime monitoring to close the gaps that source scanning alone cannot cover.
Shift-Left Integration : Embed compliance scanning early in the development lifecycle (IDE and pre-commit hooks) so developers can catch and fix misconfigurations before code is even pushed to version control.
CI/CD Pipeline Enforcement : Automate scans on every pull request or merge request using continuous integration tools (like GitHub Actions, GitLab CI, or Jenkins) to block non-compliant code from reaching deployment stages.
Policy as Code (PaC) : Define security and compliance rules using declarative languages (such as Rego with Open Policy Agent/Conftest, or Checkov/TFSec native checks) rather than relying on manual checklists.
Contextual & State-Aware Scans : Evaluate both static Infrastructure as Code (IaC) files and dry-run/planned states (e.g., Terraform plan files) to catch issues that only manifest when variables or module dependencies resolve.
Granular Feedback & Remediation Guidance : Ensure scanning tools output clear, actionable remediation advice and exact line numbers directly in developer pull requests to reduce friction and MTTR (Mean Time to Remediation).
Baseline and Exception Management : Establish a clear process for handling false positives or approved risk exceptions using inline suppressions or centralized policy exemptions with an expiration date.
Would you like me to recommend specific IaC scanning tools (such as Checkov, tfsec, or OPA/Rego) or help you design a CI/CD pipeline workflow for your team?
Implementing compliance checks for Infrastructure as a Code (IaC) files before deployment—often referred to as Shift-Left Security —helps catch misconfigurations, security vulnerabilities, and policy violations early in the development lifecycle.
Here are the recommended best practices to build a robust IaC compliance pipeline:
Shift Left by Integrating Early : Run checks as early as possible. Inject linting and static analysis into developer IDEs (via pre-commit hooks or extensions) so developers catch syntax and compliance errors before even pushing code to version control.
Automate Checks in CI/CD Pipelines : Gate your pull requests and merge requests with automated security scans. If a policy violation or critical misconfiguration is detected, automatically block the merge or deployment until it is resolved.
Treat Policies as Code : Define your compliance and security rules using code (using frameworks like Open Policy Agent/Rego or tool-native policy languages) rather than manual checklists. This ensures version control, peer reviews, and automated testing for your compliance rules themselves.
Implement Continuous Monitoring and Drift Detection : Static analysis before deployment isn't enough. Continuously scan deployed cloud environments to detect configuration drift or manual changes that violate your baseline compliance policies.
Provide Actionable Developer Feedback : Don't just fail a pipeline with a cryptic error code. Ensure your scanning tools point directly to the offending file, line number, and rule violation, while offering remediation advice or links to internal security docs.
Adopt Risk-Based Prioritization : Not all misconfigurations carry the same risk. Configure your tools to differentiate between critical vulnerabilities (e.g., public S3 buckets with sensitive data) and low-risk stylistic warnings so developers aren't overwhelmed by alert fatigue.
Leverage Industry Standards and Baselines : Map your custom or built-in rules to recognized frameworks like CIS Benchmarks, NIST, PCI-DSS, or SOC2 to streamline auditing and reporting for compliance teams.
Would you like me to recommend specific IaC scanning tools (like Checkov, tfsec, or OPA) or help you design a sample CI/CD integration workflow?
Yes. The strongest pattern is to treat IaC compliance as a pre-deployment policy gate, not merely as a static scan. The goal is to prove that the planned infrastructure is compliant before an apply/deployment can happen, while also continuously checking the deployed environment for drift.
OWASP specifically recommends integrating IaC security checks into the SDLC/CI pipeline, combining static analysis, secret detection, least privilege, artifact integrity, and continuous monitoring rather than relying on a single scanner.
1. Define compliance as code
Don't encode requirements only in documentation such as "S3 buckets must be private." Turn them into executable policies.
Before pushing Infrastructure as Code (IaC) to the cloud, the best practice is to scan locally, enforce security policies in CI/CD, and block deployments when critical compliance checks fail.
This applies to Terraform, AWS CloudFormation, Azure Bicep/ARM, Kubernetes YAML, Helm charts, and similar infrastructure definitions. NIST guidance recommends scanning IaC before it is merged or deployed, with automated checks and traceable remediation.
1. Follow these steps before pushing
Step 1 — Identify your IaC files
Inventory your Terraform (.tf), CloudFormation, Bicep, Kubernetes, Helm, and related configuration files. Include reusable modules, environment-specific variables, and deployment templates.
Step 2 — Run a static security scan
Detect insecure configurations before they become cloud resources, such as public storage, unrestricted network access, unencrypted data, excessive permissions, and missing logging.
Step 3 — Validate compliance requirements
Map your findings to the controls your organization actually needs, such as CIS Benchmarks, NIST controls, PCI DSS, or internal security standards. Add custom policy-as-code rules for requirements that generic scanners do not cover.
Step 4 — Scan for secrets and other risks
Check for exposed API keys, passwords, private keys, unsafe dependencies, and vulnerable modules. A configuration scan alone may not cover all these risks.
Step 5 — Review, fix, and gate the push
Fix critical and high-severity findings, review any exceptions, and rerun the scan. Run the same checks in pull requests and make required checks block merging when policy violations remain.
Step 6 — Verify the deployment and monitor drift
Where supported, scan a generated Terraform plan or equivalent deployment artifact. After deployment, monitor the live environment for configuration drift and violations that source-code scanning cannot detect.
These steps align with NIST's DevSecOps practices for pre-commit scanning, automated IaC analysis, remediation, and controlled code merging.
2. Choose an IaC scanning tool
These are strong starting points for a practical scanning workflow.
Trivy
Best for a straightforward, multi-purpose security scanner. Checks Terraform, CloudFormation, Kubernetes and Helm, with separate options for secret scanning and custom rules.
Best for enforcing organization-specific rules, such as approved regions, required encryption, mandatory tags, or restrictions on public network access.
My recommendation: Start with Trivy or Checkov rather than running several overlapping scanners immediately. Add OPA/Conftest if you need custom policy enforcement.
3. Run a scan locally
For a Terraform repository, Trivy provides a quick way to get started.
These commands follow the official Trivy workflow. Note that the first and second commands cover different scan modes, and the JSON report is useful for the configuration scan.
4. Define your compliance gates
Before adding the scanner to your pipeline, establish rules for what can pass.
Check
Recommended action
Critical security issue
Block the merge or deployment
High-severity issue
Block by default, with a documented exception process
Medium/low findings
Track, prioritize, and remediate according to policy
Exposed credentials
Block and rotate/revoke affected credentials
Compliance violation
Block if it violates a mandatory control
Accepted exception
Record the reason, owner, scope, and expiration
Also make sure that:
Exceptions cannot silently disable future checks.
The scanner and its policy rules are version-controlled or pinned to reviewed versions.
Pull requests include scan results and remediation details.
CI jobs produce retained reports for audit evidence.
For a centralized approach to custom checks, AWS provides an example of reusable Checkov scanning workflows and shared policies. AWS Prescriptive Guidance.
5. Tailor the workflow to your environment
I can give you exact commands and a ready-to-use pipeline configuration for your repository. Which IaC technology are you using?
Scanning your Infrastructure as Code (IaC) files before deployment—commonly known as Shift-Left Security —helps catch misconfigurations, compliance violations, and security vulnerabilities early in the development lifecycle.
Here are the recommended steps to implement an effective IaC scanning workflow:
1. Select an IaC scanning tool
Choose a tool that supports your specific IaC frameworks (Terraform, CloudFormation, Kubernetes manifests, ARM templates, Ansible, etc.). Popular options include:
Checkov : Open-source, highly popular for Terraform, Kubernetes, and CloudFormation with thousands of built-in compliance policies (SOC2, HIPAA, PCI-DSS).
Tfsec or Trivy : Fast, developer-friendly scanners by Aqua Security tailored for Terraform and broader infrastructure scanning.
KICS : Maintaining open-source scanning across multiple IaC platforms (Keeping Infrastructure as Code Secure).
environment
data_classification
Only approved regions.
Only approved instance/resource types.
IAM permissions must follow least privilege.
Terraform providers/modules must be pinned.
Modules must come from approved registries.
Certain resource types require security approval.
This is the fundamental policy-as-code model. HashiCorp currently supports Sentinel and OPA for this purpose, and describes policy enforcement as something that can either warn or prevent provisioning.
For example, conceptually:
rego
package terraform.security
deny[msg] {
resource := input.resource_changes[_]
resource.type == "aws_security_group_rule"
resource.change.after.cidr_blocks[_] == "0.0.0.0/0"
resource.change.after.from_port <= 22
resource.change.after.to_port >= 22
msg := "SSH must not be exposed to the public internet"
}
The important part isn't the particular language; it's that the rule is version-controlled, tested, reviewed, and automatically enforced.
2. Scan both the source and the resulting plan
This distinction is important.
Source-level checks
Inspect the actual IaC:
Terraform
CloudFormation
Kubernetes YAML
Helm
ARM/Bicep
Pulumi
Dockerfiles, etc.
Tools such as Trivy provide IaC misconfiguration scanning across Terraform, Kubernetes, CloudFormation and other formats.
Plan-level checks
For Terraform, also inspect:
terraform plan
↓
machine-readable plan
↓
policy engine
↓
allow / deny
This catches problems that aren't always obvious from individual .tf files because variables, modules, defaults and expressions can change the final resource configuration.
For compliance, the plan should be the authoritative pre-deployment object.
HashiCorp's policy frameworks can evaluate Terraform plan/configuration data and enforce policies as part of the Terraform workflow.
3. Separate generic security scanning from organizational policy
I'd use at least two layers.
Layer
Purpose
Examples
IaC scanner
Known security misconfigurations
Checkov, Trivy
Policy engine
Your organization's rules
OPA, Sentinel
Compliance baseline
Regulatory/security framework
CIS, NIST, PCI, etc.
Secrets scanner
Credentials accidentally committed
secret scanning tools
Dependency checks
Provider/module/image risk
dependency/SBOM tooling
Runtime scanner
What actually exists
cloud posture/configuration tools
Don't try to make one tool do everything.
For example, CIS provides cloud-specific configuration benchmarks for AWS, Azure, GCP, Kubernetes and others; these make a useful source for baseline controls.
4. Make severity and enforcement explicit
A common mistake is treating every violation identically.
I'd define something like:
Severity
Example
Action
Critical
Public database, exposed credentials
Hard fail
High
Public SSH/RDP, excessive IAM
Hard fail
Medium
Missing encryption/tag
Usually fail
Low
Naming/documentation issue
Warning
Advisory
Recommended optimization
Report only
You can also introduce an exception mechanism, but exceptions should themselves be controlled artifacts:
yaml
exception:
policy: public-load-balancer
resource: module.foo.aws_lb.main
reason: "Public ingress is required for customer API"
owner: security-team
expires: 2026-12-31
approved_by: security@example
Never allow developers to simply add something like:
yaml
skip: true
without an auditable reason, owner and expiration.
HashiCorp's Sentinel model is useful here: it supports advisory, soft-mandatory and hard-mandatory enforcement levels, with overrides recorded for non-hard policies.
This is preferable to deploying first and having a CSPM tool tell you afterward that the infrastructure violates policy.
OWASP likewise recommends automated IaC checks in CI/CD and manual review/approval for production deployment.
6. Lock down the IaC supply chain
This is frequently overlooked.
For Terraform specifically, I would require:
Exact/pinned provider versions.
Pinned module versions.
Approved module registries.
No arbitrary Git branches as module sources.
Controlled provider sources.
Review of changes to shared modules.
Version-controlled policy libraries.
Protected CI/CD configuration.
Short-lived CI cloud credentials.
No cloud access keys embedded in repositories.
HashiCorp explicitly recommends pinning providers/modules and controlling module sources as global policy guardrails.
OWASP also highlights IaC repositories, pipelines and state files as high-value attack surfaces and recommends narrowly scoped CI permissions and short-lived/federated credentials.
7. Build secure "golden modules"
Don't make every developer solve security from scratch.
For a Terraform-heavy environment, a sensible architecture would be:
Trivy or Checkov → broad IaC security/misconfiguration detection OPA/Rego → organization-specific, portable policy-as-code Sentinel → particularly attractive if you're standardized on HCP Terraform CIS Benchmarks → baseline controls Secret scanner → credentials/secrets Cloud posture/runtime scanner → validate actual deployed state
HashiCorp currently supports both Sentinel and OPA, while noting that organizations already standardized on OPA can use their existing policies.
The key architectural principle is defense in depth: scanner ≠ compliance engine ≠ runtime monitoring. You want all three.
If you tell me whether you're using Terraform, CloudFormation, Pulumi, Kubernetes, or a mix, I can also lay out a concrete CI/CD reference implementation (including the policy repository structure, OPA/Sentinel rules, severity model, exception workflow, and PR/deployment gates).
tf-constructive / cfn-lint : Specialized linters for specific cloud templates.
2. Define your compliance and security policies
Map your organization's regulatory and internal security requirements (e.g., encryption at rest, public S3 bucket prevention, mandatory resource tagging) to the scanner. Most tools allow you to use pre-built compliance frameworks or write custom policies using languages like Rego (via Open Policy Agent) or Python/YAML custom checks.
3. Integrate scanning into local development (Pre-commit)
Install the scanning tool locally or configure a pre-commit hook so developers can scan their code before even committing it to version control. This provides instant feedback and saves time.
4. Automate scans in CI/CD pipelines
Integrate the scanner into your Continuous Integration pipeline (GitHub Actions, GitLab CI, Bitbucket Pipelines) on every Pull Request or Merge Request. Configure the pipeline to block merges or flag alerts if critical or high-severity misconfigurations are detected.
5. Implement policy-as-code enforcement at deployment (Gatekeeping)
Add a final gatekeeping layer right before provisioning using tools like Open Policy Agent (OPA) or HashiCorp Sentinel embedded within your CI/CD or Terraform Cloud/Enterprise environment to ensure unverified code cannot be applied to cloud infrastructure.
6. Review, remediate, and tune rules
Establish a feedback loop to review false positives, adjust baseline policies, and guide developers on how to remediate flagged issues using automated fix suggestions or documentation links provided by the scanning tools.
Would you like assistance with:
Setting up Checkov or Trivy in a specific CI/CD pipeline?
Writing custom compliance policies for your team?
Choosing a tool based on your specific IaC stack (e.g., Terraform vs. Kubernetes)?