Skip to main content

Policies

Policies define when a version is allowed to deploy. They are the rules that govern how releases progress through your environments — controlling deployment timing through approvals, verification gates, progression requirements, deployment windows, and more.
In Ctrlplane’s mental model: Deployments = what & how, Environments = where, Policies = when.

Building Confidence Through Policies

While deployments define what and how and environments define where, policies answer the critical question of when: is this version ready to deploy? Has it passed through the right gates? Policies help you deploy with confidence by ensuring that each stage meets your quality standards before progressing to the next.
Development → QA → Staging → Production
     ↓          ↓       ↓          ↓
   (none)    smoke   integration  full
             tests     tests     gates
With policies, you can:
  • Start simple, grow complex - Begin with basic health checks in QA, add integration tests in staging, require approvals and verification in production
  • Catch issues early - Run smoke tests in QA to catch problems before they reach production
  • Automate quality gates - Let verification results automatically determine if a release can proceed
  • Reduce deployment anxiety - Know that every production deployment has passed through proven checks
  • Customize per environment - Apply stricter rules where they matter most

Policy Structure

A policy consists of:
  1. Name & Description - Identify and document the policy’s purpose
  2. Selector - A CEL expression defining which release targets the policy applies to
  3. Rules - One or more rules specifying behavior or requirements
  4. Priority - Higher priority policies are evaluated first
  5. Metadata - Arbitrary key-value pairs for organization
resource "ctrlplane_policy" "production_gates" {
  name        = "Production Gates"
  description = "Require approval and gradual rollout for production"
  priority    = 10
  enabled     = true

  selector = "environment.name == 'production'"

  any_approval {
    min_approvals = 1
  }

  gradual_rollout {
    rollout_type        = "linear"
    time_scale_interval = 300
  }
}

Policy Selectors

The selector field is a CEL expression that determines which release targets a policy applies to. Policies only affect releases that match the selector.

Environment Selector

Target releases going to specific environments:
environment.name == "production"
environment.name in ["staging", "production"]
environment.name.startsWith("prod-")
environment.metadata['tier'] == "critical"

Resource Selector

Target releases for specific resources:
resource.kind == "Kubernetes"
resource.metadata['region'] == "us-east-1"
resource.name.contains("critical")

Deployment Selector

Target releases for specific deployments:
deployment.name == "api-service"
deployment.metadata['team'] == "platform"

Combined Selectors

Combine conditions with && (AND) and || (OR):
environment.name == "production" && deployment.metadata['tier'] == "critical"

Policy Rules

Rules define what the policy enforces. A single policy can contain multiple rules across different types. Each rule in the rules array contains exactly one rule type.

Approval Rule

Require manual approval before deployment:
API FieldTerraform AttributeDescription
anyApproval.minApprovalsmin_approvalsNumber of approvals needed
See Approval for details.

Environment Progression Rule

Require successful deployment to a prerequisite environment:
API FieldTerraform AttributeDescription
environmentProgression.dependsOnEnvironmentSelectordepends_on_environment_selectorCEL matching prerequisite env
environmentProgression.minimumSuccessPercentageminimum_success_percentageRequired success % (0-100)
environmentProgression.minimumSockTimeMinutesminimum_sock_time_minutesSoak time after success
environmentProgression.maximumAgeHoursmaximum_age_hoursMax age of dependency deployment
See Environment Progression for details.

Gradual Rollout Rule

Control the pace of deployments across multiple targets:
API FieldTerraform AttributeDescription
gradualRollout.rolloutTyperollout_type"linear" or "linear-normalized"
gradualRollout.timeScaleIntervaltime_scale_intervalSeconds between targets / total time
See Gradual Rollouts for details.

Deployment Dependency Rule

Require upstream deployments to succeed first:
API FieldTerraform AttributeDescription
deploymentDependency.dependsOndepends_on_selectorCEL matching upstream deployment
See Deployment Dependency for details.

Deployment Window Rule

Control when deployments are allowed using time-based schedules:
API FieldTerraform AttributeDescription
deploymentWindow.rrulerruleRFC 5545 recurrence rule
deploymentWindow.durationMinutesduration_minutesWindow duration in minutes
deploymentWindow.timezonetimezoneIANA timezone
deploymentWindow.allowWindowallow_windowAllow during window (deny if false)
See Deployment Window for details.

Version Cooldown Rule

Batch frequent releases by enforcing a minimum time between deployments:
API FieldTerraform AttributeDescription
versionCooldown.intervalSecondsdurationMinimum time between deploys
See Version Cooldown for details.

Retry Rule

Configure automatic retry behavior for failed jobs:
API FieldTerraform AttributeDescription
retry.maxRetriesNot availableMaximum retry attempts
retry.backoffSecondsNot availableSeconds between retries
retry.backoffStrategyNot available"linear" or "exponential"
retry.maxBackoffSecondsNot availableBackoff cap
retry.retryOnStatusesNot availableWhich statuses trigger retry
See Retry for details.

Version Selector Rule

Filter which versions can deploy to specific targets:
API FieldTerraform AttributeDescription
versionSelector.selectorNot availableCEL expression or JSON selector
versionSelector.descriptionNot availableHuman-readable description
See Version Selector for details.

Verification Rule

Run automated checks after deployment: See Verification for detailed configuration options.

Terraform Provider Reference

The Terraform provider supports the following policy blocks:
BlockDescription
any_approvalRequire manual approvals
environment_progressionRequire success in prerequisite environments
gradual_rolloutStagger deployments over time
deployment_dependencyRequire upstream deployments to succeed first
deployment_windowTime-based deployment scheduling
version_cooldownBatch frequent releases
verificationAutomated health checks
retry and version_selector are not yet available in the Terraform provider. Use the REST API for these rule types.

REST API Reference

Create a policy:
POST /v1/workspaces/{workspaceId}/policies
Get/Update/Delete a policy:
GET    /v1/workspaces/{workspaceId}/policies/{policyId}
PUT    /v1/workspaces/{workspaceId}/policies/{policyId}
DELETE /v1/workspaces/{workspaceId}/policies/{policyId}
List policies:
GET /v1/workspaces/{workspaceId}/policies
Each rule in the rules array is an object with exactly one rule-type key (e.g., anyApproval, gradualRollout, deploymentWindow).

Policy Evaluation

When a release is created, Ctrlplane:
  1. Finds matching policies - Evaluates the selector CEL expression against each release target
  2. Merges rules - Combines rules from all matching policies
  3. Applies rules - Enforces each rule type

Rule Interactions

  • Approval + Gradual Rollout: The rollout start time is determined by when the approval was satisfied
  • Environment Progression + Gradual Rollout: The rollout waits until progression criteria are met
  • Deployment Window + Gradual Rollout: Allow windows push the rollout start to the window opening; deny windows pause the rollout
  • Version Cooldown + Deployment Window: Both must be satisfied — cooldown determines which version, window determines when

Common Patterns

Environment Progression

Different requirements per environment:
resource "ctrlplane_policy" "staging_policy" {
  name     = "Staging Policy"
  selector = "environment.name == 'staging'"

  environment_progression {
    depends_on_environment_selector = "environment.name == 'qa'"
  }
}

resource "ctrlplane_policy" "production_policy" {
  name     = "Production Policy"
  selector = "environment.name == 'production'"

  any_approval {
    min_approvals = 1
  }

  environment_progression {
    depends_on_environment_selector = "environment.name == 'staging'"
    minimum_sock_time_minutes       = 30
  }

  gradual_rollout {
    rollout_type        = "linear"
    time_scale_interval = 300
  }
}

Critical Service Protection

Extra protection for critical services:
resource "ctrlplane_policy" "critical_service_gates" {
  name     = "Critical Service Gates"
  selector = "deployment.metadata['tier'] == 'critical' && environment.name == 'production'"
  priority = 20

  any_approval {
    min_approvals = 2
  }

  gradual_rollout {
    rollout_type        = "linear"
    time_scale_interval = 600
  }
}

Best Practices

Policy Organization

  • ✅ Use descriptive policy names
  • ✅ Document policy purpose in description
  • ✅ Start with permissive policies and tighten over time
  • ✅ Test policies in lower environments first
  • ✅ Use priority to control evaluation order for overlapping policies

Selector Design

  • ✅ Be specific with selectors to avoid unexpected matches
  • ✅ Use environment selectors for environment-specific rules
  • ✅ Use metadata for cross-cutting concerns (team, tier, etc.)
  • ✅ Test selector expressions before applying

Rule Configuration

  • ✅ Set reasonable timeouts and failure limits
  • ✅ Use verification to catch issues before they impact users
  • ✅ Require approvals for high-risk deployments
  • ✅ Use gradual rollouts for large-scale deployments
  • ✅ Combine complementary rules (e.g., approval + gradual rollout)

Next Steps