Policy as Code (PaC) is often discussed in the context of security and compliance, but its power extends far beyond that. One of the most impactful applications of PaC is in the domain of FinOps, where it can transform cloud financial management from a reactive, report-driven exercise into a proactive, automated discipline.

By defining cost controls as code, you can empower engineering teams to build and innovate quickly while providing the finance and operations teams with the assurance that budgets are being respected. This guide explores practical ways to apply Policy as Code to achieve your FinOps goals.

The "Inform" Phase: Enforcing Visibility with Tagging Policies

The foundation of any successful FinOps practice is visibility. You cannot optimize what you cannot see. Policy as Code is the most effective way to enforce a consistent tagging strategy, ensuring you always have the data needed for accurate cost allocation.

Terraform Policy: Require `CostCenter` Tag

This policy, embedded directly in your Terraform variable definitions, ensures that no resources can be deployed without an associated cost center, failing at the `plan` stage.

variable "cost_center" {
  type        = string
  description = "The cost center for the deployed resources. This tag is mandatory."

  validation {
    # Fail if the variable is empty or null
    condition     = length(var.cost_center) > 0
    error_message = "The 'cost_center' variable must be set for cost allocation."
  }

  validation {
    # Optional: ensure the value is in an approved list
    condition     = contains(["engineering", "marketing", "data-science"], var.cost_center)
    error_message = "Invalid cost center. Must be one of the approved values."
  }
}

resource "aws_vpc" "main" {
  # ... other configuration
  tags = {
    CostCenter = var.cost_center
    Owner      = "infra-team"
  }
}

The "Optimize" Phase: Preventing Waste with Resource Policies

This is where Policy as Code delivers direct cost savings by preventing waste before it happens. Instead of cleaning up oversized instances at the end of the month, you prevent them from ever being created.

OPA/Rego Policy: Restrict Expensive VM Types

This policy inspects a Terraform plan and denies the creation of expensive, high-memory virtual machines in a development environment.

package terraform.finops

# List of forbidden, expensive instance types for non-production
forbidden_dev_instances := {"m5.24xlarge", "r5.24xlarge", "p4d.24xlarge"}

# Deny if a planned AWS instance uses a forbidden type in a dev workspace
deny[msg] {
    resource := input.resource_changes[_]
    resource.type == "aws_instance"
    resource.change.actions[_] == "create"
    
    workspace_name := input.workspace_name
    startswith(workspace_name, "dev-")

    instance_type := resource.change.after.instance_type
    forbidden_dev_instances[instance_type]
    
    msg := sprintf("Resource '%v' uses a forbidden instance type '%v' for the '%v' environment.", [
        resource.address,
        instance_type,
        workspace_name
    ])
}

The "Operate" Phase: Automating Cleanup and Budget Alerts

Finally, PaC can help automate the ongoing operational tasks of FinOps, such as identifying idle resources and enforcing budget limits within your CI/CD pipeline.

Rego Policy: Identify Idle EBS Volumes

This policy scans your cloud asset inventory and identifies EBS volumes that are unattached ("available"), representing pure waste.

package finops.idle_resources

# Identify volumes that are not attached to any instance
idle_volumes[info] {
    volume := input.aws.ebs_volumes[_]
    volume.state == "available"
    # Ignore small volumes or those created in the last 24 hours
    volume.size_gb > 10
    time.now_ns() > time.parse_rfc3339_ns(volume.create_time) + (time.hour * 24)

    info := {
        "VolumeId": volume.volume_id,
        "Size": volume.size_gb,
        "Region": volume.region,
        "Cost": volume.monthly_cost
    }
}

# Generate a violation message for each idle volume
violation[msg] {
    some info in idle_volumes
    msg := sprintf("Idle Resource Alert: EBS Volume %v (%v GB) is unattached, costing approximately $%v/month.", [
        info.VolumeId,
        info.Size,
        info.Cost
    ])
}

CI/CD Pipeline: Budget Enforcement

This conceptual GitHub Actions step uses `terraform plan` to estimate costs and fails the build if the planned cost exceeds a set budget.

    - name: Check Terraform Plan Cost
      id: cost
      run: |
        terraform plan -out=tfplan
        COST=$(terraform show -json tfplan | infracost breakdown --path - --format json | jq -r '.totalMonthlyCost')
        echo "PLANNED_COST=${COST}" >> $GITHUB_ENV

    - name: Enforce Budget
      if: steps.cost.outputs.PLANNED_COST > 1000
      run: |
        echo "Error: Planned cost (${env.PLANNED_COST}) exceeds monthly budget of $1000."
        exit 1

Conclusion: From Gatekeeper to Enabler

By using Policy as Code for FinOps, you shift cost governance from a reactive, manual process to a proactive, automated discipline. This empowers developers by giving them fast feedback within their existing workflows and provides finance teams with the predictability and control they need to manage cloud spend effectively.