Why Policy-as-Code Matters
The Governance Challenge
Managing infrastructure at scale gets complicated fast.
As your infrastructure grows, ensuring consistency and compliance becomes increasingly difficult. Manual reviews don’t scale, and configuration drift is inevitable. You need automation that enforces standards without becoming a bottleneck.
Common Infrastructure Issues
- Developers accidentally making resources publicly accessible
- Missing required tags on cloud resources
- Non-compliant security group configurations
- Kubernetes deployments without resource limits
- Terraform modules bypassing organizational standards
The Problem: Manual Governance
Why Manual Reviews Fail
Relying on manual code reviews and post-deployment checks is inefficient and error-prone. Standards get ignored, security policies get bypassed, and by the time issues are caught, they’re already in production. You need guardrails that prevent problems before deployment.
Real-World Impact
When policies aren’t enforced, organizations face:
- Security breaches from misconfigured resources
- Compliance violations leading to audits and fines
- Cost overruns from unoptimized infrastructure
- Operational chaos from inconsistent deployments
The Solution: Open Policy Agent (OPA)
What is OPA?
Open Policy Agent is a unified policy engine that decouples policy logic from application logic. It evaluates policies written in Rego (a declarative language) against any kind of data Terraform plans, Kubernetes manifests, CI/CD configurations, and more.
Key Benefits
- Unified enforcement across Terraform, Kubernetes, and custom tools
- Declarative policies that are easy to understand and maintain
- Pre-deployment validation to catch issues before they reach production
- Audit trails for compliance and governance requirements
- Organization-wide standards enforced consistently
Getting Started with OPA and Rego
Installation
# macOSbrew install opa
# Linuxcurl -L -o opa https://openpolicyagent.org/downloads/latest/opa_linux_x86_64chmod +x opasudo mv opa /usr/local/bin/Basic Rego Policy
# Deny public S3 bucketspackage s3
deny[msg] { input.resource_type == "aws_s3_bucket" input.acl == "public-read" msg := sprintf("S3 bucket %s cannot be public", [input.name])}
deny[msg] { input.resource_type == "aws_s3_bucket" input.acl == "public-read-write" msg := sprintf("S3 bucket %s cannot be public", [input.name])}Integrating OPA with Terraform
Using Conftest (OPA CLI for Terraform)
# Install conftestbrew install conftest
# Validate Terraform planterraform plan -json | conftest test -Policy Example: Enforce Tags
package terraform
deny[msg] { resource := input.resource_changes[_] resource.type in ["aws_instance", "aws_rds_cluster"] not resource.change.after.tags.Environment msg := sprintf("Resource %s must have Environment tag", [resource.address])}
deny[msg] { resource := input.resource_changes[_] resource.type in ["aws_instance", "aws_rds_cluster"] not resource.change.after.tags.CostCenter msg := sprintf("Resource %s must have CostCenter tag", [resource.address])}Enforcing Policies in Kubernetes
OPA Gatekeeper Installation
# Deploy Gatekeeper to your clusterkubectl apply -f https://raw.githubusercontent.com/open-policy-agent/gatekeeper/release-3.14/deploy/gatekeeper.yamlKubernetes ConstraintTemplate
apiVersion: constraints.gatekeeper.sh/v1beta1kind: K8sRequiredResourcesmetadata: name: require-resource-limitsspec: match: kinds: - apiGroups: [''] kinds: ['Pod'] excludedNamespaces: ['kube-system', 'gatekeeper-system']---apiVersion: templates.gatekeeper.sh/v1kind: ConstraintTemplatemetadata: name: k8srequiredresourcesspec: crd: spec: names: kind: K8sRequiredResources targets: - target: admission.k8s.gatekeeper.sh rego: | package k8srequiredresources
violation[{"msg": msg}] { container := input.review.object.spec.containers[_] not container.resources.limits.cpu msg := sprintf("Container %s must have CPU limit", [container.name]) }
violation[{"msg": msg}] { container := input.review.object.spec.containers[_] not container.resources.limits.memory msg := sprintf("Container %s must have memory limit", [container.name]) }CI/CD Pipeline Integration
GitHub Actions Example
name: Policy Validation
on: [pull_request]
jobs: policy-check: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3
- name: Install OPA run: | curl -L -o opa https://openpolicyagent.org/downloads/latest/opa_linux_x86_64 chmod +x opa sudo mv opa /usr/local/bin/
- name: Run Policy Tests run: | opa test policies/ -v
- name: Validate Terraform if: hashFiles('*.tf') != '' run: | terraform init terraform plan -json | opa eval -d policies/ 'data.terraform.deny' -f prettyBest Practices
1. Organization-First Approach
Define policies at the organization level, not project level. Make them discoverable and documented.
# Start with clear policy namespacespackage org_policies.infrastructure.aws.securitypackage org_policies.kubernetes.workload2. Fail Safely
Distinguish between hard denials and warnings:
package my_policies
deny[msg] { # Hard deny: completely block this input.security_critical_violation == true msg := "This violates critical security policy"}
warn[msg] { # Warning: recommend but allow with approval input.non_standard_naming == true msg := "Consider following naming standards"}3. Test Your Policies
# Test policy logic before deploymentopa test policies/ -v4. Version Control Policies
Keep policies in the same repo as infrastructure code, with proper code review processes.
Monitoring and Auditing
Log Policy Violations
Capture and log every policy decision for audit trails:
package audit
log_decision[decision] { decision := { "action": "denied", "reason": input.violation_reason, "timestamp": input.timestamp, "resource": input.resource_id }}Real-World Implementation Timeline
| Phase | Focus | Timeline |
|---|---|---|
| Phase 1 | Basic security policies (public access, required tags) | Week 1-2 |
| Phase 2 | Terraform integration in CI/CD | Week 3-4 |
| Phase 3 | Kubernetes Gatekeeper deployment | Week 5-6 |
| Phase 4 | Comprehensive auditing and monitoring | Week 7-8 |
Conclusion
Policy-as-Code transforms governance from reactive to proactive.
Using OPA and Rego, you can enforce organizational standards consistently across Terraform, Kubernetes, and custom systems. Start with critical security policies, gradually expand coverage, and build a culture where compliance is automatic, not manual.